Jump to: navigation, search

Trove/extensionsrefactor

Dynamic route proposal

Changes

  • Remove existing extensions and move routes mapped into base API app. Ex: instances/<instance_id>/users
  • Add code to inspect instance_id and map it to an instance type.. Redis Postgres MySQL etc.
  • Have "proxy" route dynamically load a service for each database type either with importlib or stevedore whatever.
  • Have the route dynamically accept requests for special edge cases for differing database engines.
    • Ex: Default database required for postgres on user create while MySQL does not use one.

Why do it this way?

  • Does not change existing API URL spec. No need to version API.
  • Fewer routes in API vs having prefix/namespace based approach for commonly supported requests like users or backup.
    • Ex /instances/<instance_id>/mysql/users.
    • Ex /instances/<instance_id>/postgres/users.
    • Ex /instances/<instance_id>/mongodb/users.
  • Allows for multiple versions or forks of different Database engines more easily.
    • Ex: Allow multiple versions of a Database engine that have differing user create requirements.. (Can't think of anything that exactly matches that scenario so maybe this is a bad example. However, it does allow for differing versions of one database application.)
    • This could be true of the namespaced option as well
  • Allows the interface for users who only want to support one DB engine to be simplified.
    • Ex: No database type specific URI prefix.
  • Allows the base URI mappings to be the same for all databases that have a common type.
    • Ex: users, backups etc.
  • More like the nova API.
  • Conrad likes this one more =P.

Cons

  • Less explicit then using database specific prefixes.
  • Post body may vary significantly based on database type
  • Harder to create a schema for.
  • More difficult to write JsonSchema stuff for.
  • Harder to document without referring to various database types within most entries.
  • If you think about writing the client, it would probably lead to the creation of an even larger "God object" for Instance.

Alternative Solutions

Use a db-specific/namespaced routing methodology

Changes

  • Remove or deprecate existing extensions and move routes mapped into base API app. Ex instances/<instance_id>/<db_type>/users
Alternate example: <db_type>/instances/<instance_id>/users for users of a specific db_type, instances/<instance_id>/action for an action that could apply to any instance. 
  • Add code to inspect instance_id and verify it's instance type.. Redis Postgres MySQL etc.
  • Have "proxy" route dynamically load a service for each database type either with importlib or stevedore whatever.
  • Have the route accept requests for differing database engines. Ex. Default database for postgres on user create while MySQL does not use one.

Why do it this way?

  • More explicit than dynamic type mapping.
  • Might be easier to write docs as each URI is explicit rather than implicit based off of its type.
  • Contract is explicit for each URI rather than variable based on database type.
  • Databases with similar functionality could use polymorphism to override or extend functionality of the routing modules
  • hub_cap is all about this one!
  • Kenneth is currently on this side of the fence

Cons

  • Potential api version change. (If existing extentions and routes are removed)
  • Could be wonky for users only using one DB type.
    • A solution for that edge case may be to implement aliasing for instances/<instance_id>/<action> and that is the same as supporting dynamic type resolution essentially.
  • Lots of routes to manage depending on how we decide to implement the routing.
    • These could be handled by routing modules for each database type
  • Need to know what type db is in order to know what uri to post to.

Client Examples

Client interaction flow with dynamic type resolution for user add example

  • Determine type from instances listing.
  • post to instances/<instance_id>/users with db specific body.
  • validate input.
  • 404 if db does not have concept of users.
  • 2** if all is well

Client interaction flow with namespaced routes for user add example

  • Determine type from instance listing.
  • post to instances/<instance_id>/<db_type>/users with db specific body.
  • validate input.
  • 404 if db does not have concept of users. (Comment: if the db type was explicit in the request, why would this ever happen? It would be very clear from the docs that the path was invalid and the Python client bindings, as well as other bindings, would not allow it.)
  • 2** if all is well.