Search code examples
sails.jssails-mongo

Correctly using SailsJs policies, services and models


I'm new to NodeJs and SailsJs so be nice.

I've been using policies to complete a POST request which will eventually create a new model;

  1. Policy to check that all request parameters are present, if any are missing then respond with 404 or similar
  2. Policy which calls a service to check that some model exists in the database and it has the correct state for the request to take place. This policy may add additional parameters to the request for use later when creating the new model.
  3. Same as above for a different model.
  4. Now we know the two models are present and correct we can amend them using a similar service used in steps 3 and 4.
  5. Call OnCreate for the newly created model now all our policies have been passed, this will do some final amends to the newly created model.

The policies seem like a good idea in order to check a request and add additional parameters to the request. But it just seems a bit cumbersome. That I need to check everything before finally making amends to other models.

It seems like transactions would help here as that would allow me to check and update all at the same time.

I'm using MongoDb.


Solution

  • Might be worth me quoting from "Sails in action" as I was actually reading their best practice for policies this morning!

    Policies shouldn't be a core part of your business logic Policies are not a good tool for structuring logic in your app. Using them this way makes them just as versatile as raw Express/Connect middleware-- and unfortunately it also makes them just as dangerous and developer-specific. If you use policies to help with queries, or create a complex chain of policies to manage permission systems in your applicaiton, you are likely to create a code base that is very difficult for any other developer to understand.

    With that being said it goes on to suggest:

    Policies are not a good tool for structuring logic in your app. Using them this way makes them just as versatile as raw Express/Connect middleware-- and unfortunately it also makes them just as dangerous and developer-specific. If you use policies to help with queries, or create a complex chain of policies to manage permission systems in your applicaiton, you are likely to create a code base that is very difficult for any other developer to understand.

    Based on the above quotes, and in my opinion you are right to question the usage of policies. I think what you are describing is definitely edging into the world described by the first quote (near the end).

    For me I'd be calling services where possible. In essence if I end up using the code 3+ times across multiple files then it needs to live in a service. If the code is custom to each action then it's fine to sit in the controller. The parameter checks you have fall into a controller action, unless you build a service you can supply some options into for validation.

    I check the params in the controller, but at what point do you think it may even be more useful to perform the validation at the model level? Regardless to what is received, the model needs to be satisfied that it has valid attributes. Maybe move the logic closer to your model and out of the services arena.

    Happy to discuss further, the benefit of sails is that there is never a best practice, but some people have felt the pain before and can offer some guidance.

    Don't look at parameters - Truly reusable policies should only look at req.session and the database- NOT at parameters! Relying on parameters makes your policy context-specific and only usable in very specialized circumstances. And in that case, why not just put the code in the relevant action(s)?