0

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.

Jake N
  • 10,535
  • 11
  • 66
  • 112

2 Answers2

2

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)?

munkee
  • 759
  • 1
  • 9
  • 23
  • Thanks @munkee for this. Its a big help! It looks like I should be overriding the default actions in the generated controllers. So rather than performing checks, validation, etc in a policy I should be doing it inside the `create` function in my controller. I did do this, but there did not seem to be an easy way to then go on and perform the default `create` action after my custom code has run? Other than copying the default code into my own `create` action? – Jake N May 18 '16 at 14:48
  • As a rule of thumb I would leave the create action alone to do what it does as standard. I would create a new action to cover anything specific, heck I could even call it "customcreate" if needs be. I 100% recommend purchasing the Sails.js in action book as I can relate to lots of your points in these posts and it wasn't until I took a look through certain chapters that I saw some of the pitfalls being talked about and what is "best practice". In short though, the recommendations are always to keep the default blueprint actions untouched (99% of cases) – munkee May 18 '16 at 18:21
  • 1
    Thanks again. I'm not sure how that will work for me as there are several models that need checking and changing for a crest for example. create seems like the right place to put those, where else would I put them? In life cycle events? – Jake N May 18 '16 at 18:25
  • In scenarios like this I think its well worth just going for what you feel is best. I don't know your full app architecture to say what is the best way right now but I think the points we've discussed show there are some areas where you wouldn't typically put the logic. If you feel life cycle events could work give it a go. As a worst case scenario you are refactoring at some point but you will have learnt way more by trying. Sails is great for these scenarios and I'm glad it allows multiple options instead of other frameworks that would force you to go their way or "no way". – munkee May 19 '16 at 07:26
1

I'm new in SailsJS too. I'm using policy just to verify authentication and insert logged user in the request (when I need it). For other verifications I use beforeCreate(...) Lifecycle callback

Makah
  • 4,435
  • 3
  • 47
  • 68