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.
When to use a model action
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 themselves to contact that person later, a developer might implement a model action called scheduleFollowUp on the contact model.
Because scheduleFollowUp concerns following up with a specific contact, this action should be a model action.
Model action ids
Because model actions operate on specific records, they often take an id parameter in the auto-generated 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
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.
When to use a global action
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 vs model actions
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.
Global actions vs HTTP routes
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 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 frontend directory of your application by Gadget's frontend hosting.
HTTP Routes can be called in React with the useFetch hook, and global actions can be called with the useGlobalAction hook. 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.