When you run sails lift
with blueprints enabled, the framework inspects your models and configuration in order to bind certain routes automatically. These implicit blueprint routes (sometimes called "shadow routes", or even just "shadows") allow your app to respond to certain requests without you having to bind those routes manually in your config/routes.js
file. When enabled, the blueprint routes point to their corresponding blueprint actions (see "Action routes" below), any of which can be overridden with custom code.
There are four types of blueprint routes in Sails:
REST blueprints are the automatically generated routes Sails uses to expose a conventional REST API for a model, including find
, create
, update
, and destroy
actions. The path for RESTful routes is always /:modelIdentity
or /:modelIdentity/:id
. These routes use the HTTP "verb" to determine the action to take.
For example, with rest
enabled, having a Boat
model in your app generates the following routes:
find
blueprint.findOne
blueprint.create
blueprint.update
blueprint.destroy
blueprint.If the Boat
model has a “to-many” relationship with a Driver
model through an attribute called drivers
, then the following additional routes would be available:
:fk
value to the drivers
collection of the boat with the ID given as :id
, using the add
blueprint.:fk
value to the drivers
collection of the boat with the ID given as :id
, using the remove
blueprintdrivers
collection with the drivers whose unique IDs are contained in an array provided as the body of the request, using the replace
blueprint.Depending on the style of app you generated, rest
blueprint routes may be enabled by default, and could be suitable for use in a production scenario, as long as they are protected by policies to avoid unauthorized access. If you choose the "Web app" template, rest
blueprint routes will not be enabled by default.
Be forewarned: Most web apps, microservices, and even REST APIs eventually need custom features that aren't really as simple as "create", "update", or "destroy". If/when the time comes, don't be afraid to write your own custom actions. Custom actions and routes can, and in many cases should, still be organized as a RESTful API, and they can be mixed and matched with blueprints when necessary. Best of all, thanks to the introduction of async/await in Node.js, writing custom actions no longer requires the use of callbacks.
- If CSRF protection is enabled, you'll need to provide or disable a CSRF token for POST/PUT/DELETE actions, otherwise you will get a 403 Forbidden response.
- If your app contains a controller whose name matches that of your model, then you can override the default actions pointed to by the RESTful routes by providing your own controller actions. For example, if you have an
api/controllers/BoatController.js
controller file containing a customfind
action, then theGET /boat
route will point at that action.- Also, as usual, the same logic applies whether you're using controllers or standalone actions. (As far as Sails is concerned, once an app has been loaded into memory and normalized in
sails lift
, all of its actions look the same no matter where they came from.)- If your app contains a route in
config/routes.js
that matches one of the above RESTful routes, it will be used instead of the default route.
Shortcut routes are a simple (development-mode only) hack that provides access to your models from your browser's URL bar.
The shortcut routes are as follows:
Route | Blueprint Action | Example URL |
---|---|---|
GET /:modelIdentity/find | find | http://localhost:1337/user/find?name=bob |
GET /:modelIdentity/find/:id | findOne | http://localhost:1337/user/find/123 |
GET /:modelIdentity/create | create | http://localhost:1337/user/create?name=bob&age=18 |
GET /:modelIdentity/update/:id | update | http://localhost:1337/user/update/123?name=joe |
GET /:modelIdentity/destroy/:id | destroy | http://localhost:1337/user/destroy/123 |
GET /:modelIdentity/:id/:association/add/:fk | add | http://localhost:1337/user/123/pets/add/3 |
GET /:modelIdentity/:id/:association/remove/:fk | remove | http://localhost:1337/user/123/pets/remove/3 |
GET /:modelIdentity/:id/:association/replace?association=[1,2...] | replace | http://localhost:1337/user/123/pets/replace?pets=[3,4] |
Shortcut routes should always be disabled when Sails lifts in a production environment. But they can be very handy during development, especially if you prefer not to use the terminal.
- Like RESTful routes, shortcut routes can be overridden by providing an action in a matching controller, or by providing a route in
config/routes.js
.- the same action is executed for similar RESTful/shortcut routes. For example, the
POST /user
andGET /user/create
routes that Sails creates when it loadsapi/models/User.js
will respond by running the same code (even if you override the blueprint action)- When using a NoSQL database (like MongoDB) with your model’s
schema
configuration set tofalse
, shortcut routes will interpret any parameter value for an unknown attribute as a string. Be careful doinghttp://localhost:1337/game/create?players=2
if you don’t have aplayers
attribute with anumber
type!
When action shadow routes (or "action shadows") are enabled, Sails will automatically create routes for your custom controller actions. This is sometimes useful (especially early on in the development process) for speeding up backend development by eliminating the need to manually bind routes. When enabled, GET, POST, PUT, and DELETE routes will be generated for every one of a controller's actions.
For example, if you have a FooController.js
file with a bar
method, then a /foo/bar
route will automatically be created for you as long as sails.config.blueprints.actions
is enabled. Unlike RESTful and shortcut shadows, implicit, per-action shadow routes do not require that a controller has a corresponding model file.
If an index
action exists, additional naked routes will be created for it. Finally, all actions
blueprints support an optional path parameter, id
, for convenience.
Since Sails v1.0, action shadows are disabled by default. They can be OK for production-- however, if you'd like to continue to use controller/action autorouting in a production deployment, you must take great care not to inadvertently expose unsafe/unintentional controller logic to GET requests. You can easily turn off a particular method or path in your /config/routes.js
file using the response target syntax, for example:
'POST /user': {response: 'notFound'}
- Action routes respond to all HTTP verbs (GET, PUT, POST, etc.). You can use
req.method
inside an action to determine which method was used.
When action shadows (sails.config.blueprints.actions
) are enabled, an additional, root shadow route is automatically exposed for any actions that happen to be named index
. For example, if you have a FooController.js
file with an index
action in it, a /foo
shadow route will automatically be bound for that action. Similarly, if you have a standalone action at api/controllers/foo/index.js
, a /foo
route will be exposed automatically on its behalf.
Read more about configuring blueprints in Sails, including how to enable / disable different categories of blueprint routes.