API
TODO: api info
API Endpoint Best Practices
Dare
This section is still WIP so won't answer all of your questions...
Take a look at the dare repo to see how the base package works, this will focus more on how it is implemented in the hub along with a few tips.
Dare models
Dare models define how the tables in the database link together and enforce some security and business logic. They are used whenever you make a dare request to turn what you have written into the SQL to run against the database. See the dare documentation for full details of models.
We have two sets of models in the hub:
- models (api/db/models) - these define the basic structure of the tables but don't enforce much business logic. These are used when you make dare request via the api function from within the api. These don't get used directly when you make calls from the front-end.
- modelsRest (api/db/modelsRest) - these extend the basic models to enforce security and business logic. This means that a customer with sufficient knowledge of our database structure would be able to write queries against our api to get the data that they need with all the restrictions of which data they can access and with all business rules applied automatically for them.
Mutation handlers
The modelsRest models contain many mutation handlers which modify the request, enforce tenancy and apply access permissions. These are used to filter results and check assigned values are in the scope of the tenancy. And are applied to get, post, patch and del functions in those files. If a function is missing such as del then the default handling is to dismiss the request.
When these functions run, they are running before the database request has taken place, so they are allowing you to modify what is going to be done to the database. If you want to run something after the database has been updated, e.g. if you want to re-calculate playlist completion rates, then this has to be done by defining a function for dareInstance.after which will run immediately after. See After handlers docs.
So the order that things are runs is mutation handler > dare query > after handler.
The exception to all of this is if you set options.skip in a handler. This will prevent the dare query from being run and is used when you are going to write all the logic in the handler. In this case it will run the mutation handler followed by the after handler.
Things to be careful of:
- calls made from within the api to the api function use the base models which don't enforce security or business logic which is enforced in the rest endpoint. You will need to specify the restrictions on the query such as domain_id, and will need to ensure that any extra actions such as logging takes place. This can catch you out if you're moving from coding the front-end where it's all done for you to using it in the api where you have to do the thinking yourself