Model actions are actions that run in the context of specific records within a model. Model actions are invoked on a particular
record object from their model, and are passed that record each time they are run.
Actions that center around creating, updating, or deleting a specific record in the database are best expressed as model actions.
For example, in a CRM application, we might have a model representing a
contact. If a salesperson wants to remind themself to contact that person later, a developer might implement a model action called
scheduleFollowUp on the
scheduleFollowUp concerns following up with a specific contact, this action should be a model action.
Because model actions operate on specific records, they often take an
id parameter in the autogenerated API. This
id parameter is the
id of the record that the action is being invoked on. Gadget will load the record with this id, and pass it as the
record object in the action's context.
Create actions don't accept an
id, as they are creating a new record. Instead, they get passed an unsaved record populated with the default values for each field.
Global actions are actions that do not operate in the context of a specific record or model. Global actions aren't passed any
record objects and don't accept any
id parameters by default.
Actions that touch many records from many models, or that mainly interface with other systems are often best expressed as global actions. If there isn't a clear central record, global actions are generally recommended.
For example, in a CRM system, a developer might need to implement an action to send a weekly report to all the executives at a company. This report doesn't concern one particular user or one particular contact and instead relates to many different records. This global action can still read data from other records, but because it doesn't concern one central one, it's easiest to implement as a global action.
Global actions are similar to model actions in that they operate using the action framework.
However, model actions are tied to a specific model and are used when you want to operate on a specific instance of that model. For instance, if you have a User model and you want to create an action that changes the user's password, you would use a model action. This action would be tied to a specific user and would operate on that user's data.
On the other hand, global actions are not tied to any specific model. They are used when you want to perform an operation that doesn't necessarily relate to a specific instance of a model. For example, if you wanted to create an action that sends a newsletter email to all users, you would use a global action. This action isn't tied to a specific user but rather operates on all users.
The choice between a model action and a global action depends on the specific requirements of the operation you want to perform.
In addition to global actions, you can also add HTTP routes to your application. HTTP Routes are similar to Global Actions in that they run code, use your app's
api object to touch data, and aren't defined on any one model in particular.
There are key differences between global actions and HTTP Routes:
- Global actions can be run as database transactions.
- Global actions can be triggered on a schedule.
- Global actions are included by default in your app's generated GraphQL API. This means that they are easily invoked from your JS client with type safety, input validation, a common error format, performant data fetching, etc. With HTTP routes, each route is responsible for its own typing, error handling, input validation, etc.
- HTTP Routes can return arbitrary content, like CSS files, images, PDFs, streams of text, or nothing at all. global actions can only return JSON via the GraphQL API. Global actions cannot serve frontend code (HTML, CSS, etc). Frontend code is served within the
frontenddirectory of your application by Gadget's frontend hosting.
- HTTP Routes can be called in React with the
useFetchhook, and global actions can be called with the
useGlobalActionhook. Both these hooks will pass authentication information from the client.
Gadget recommends using global actions when possible because of the added benefits of being included in the Gadget app's GraphQL API.