Does anyone have ideas on maintaining multiple versions of your API when using sails.js? Imagine a simple example like:
// Request
GET /api/v1/catVids?min_view_count=10000
// Response
[{"video_title": "top cat fails"}, {"video_title": "funny-ass cats"}]
Users are actively consuming v1 of the API but something has now changed in the requirements that will break existing functionality. For example, an attribute name change. So now we need to utilize a different controller to fulfill requests for this new behavior. What I would like to do is have both APIs co-exist so backwards compatibility is not broken.
// Request
GET /api/v2/catVids?minimum_view_count=10000
// Response
[{"title": "top cat fails"}, {"title": "funny-ass cats"}]
However, I'm unsure on the best way to implement this. One way I think it could work is to use the following directory setup within the sails app:
api/
|-- controllers/
|---- v1/
|------ CatController.js
|---- v2/
|------ CatController.js
|-- models/
|---- v1/
|------ Cat.js
|---- v2/
|------ Cat.js
I'm just wondering if anyone else has ran into a similar scenario or has any suggestions on the topic.
Apply API Versioning Best Practices With AkanaEnsure backwards compatibility. Keep API documentation up-to-date. Adapt to business requirements. Automate security in your API versions.
js (or Sails) is a model–view–controller (MVC) web application framework developed atop the Node. js environment, released as free and open-source software under the MIT License. It is designed to make it easy to build custom, enterprise-grade Node. js web applications and APIs.
You can get away with putting your controllers in subdirectories as in your example, because nested controllers are fully supported by Sails. However, nested models are not fully supported because of the ambiguity they would cause (see this comment on the matter). If you put two model files both named Cat.js in separate subfolders, they'll collide and the second one will overwrite the first in memory when Sails lifts.
That's sort of an academic point though, since you'll need some way to distinguish between your two model versions anyway in code. That is, in your v1 controller you'll want to make sure you're referencing your v1 Cat
model, and likewise for v2. The simplest solution would be to go with a scheme like you have in your example, but add a suffix to your models (or at least everything after v1):
api/
|-- controllers/
|---- v1/
|------ CatController.js
|---- v2/
|------ CatController.js
|-- models/
|---- v1/
|------ Cat.js
|---- v2/
|------ Cat_v2.js
The subfolder for the models will be ignored by Sails, so to make sure your blueprints work the way you want, you can add a _config
property to your controllers to force them to use the correct model.
api/controllers/v1/CatController.js:
module.exports = {
_config: {
model: 'cat'
},
...
}
api/controllers/v2/CatController.js:
module.exports = {
_config: {
model: 'cat_v2'
},
...
}
The usage of _config
in a controller is no longer valid in Sails 1.0. Instead, you can use the parseBlueprintOptions
config function to set which model a blueprint operates on, e.g.:
parseBlueprintOptions: function(req) {
// Get the default query options.
var queryOptions = req._sails.hooks.blueprints.parseBlueprintOptions(req);
// Add the _v2 suffix to the `using` property.
queryOptions.using = queryOptions.using + '_v2';
return queryOptions;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With