The gadget-server package is an autogenerated package of utilities for implementing your Gadget app's backend.
Exports from gadget-server are only available in the backend of your application, and not on the frontend. For reading and writing
data from your frontend, see the @gadgetinc/react package.
This api client has the system-admin role and can perform any action in your Gadget app.
See the API Reference for more information on your app's API and the api client object.
trigger
An instance of the triggers associated with your Gadget app's action. When an action is executed, it receives a trigger object containing information about the event that initiated the action. This object varies depending on the trigger type and includes a type property that specifies the kind of trigger.
api/models/someModel/actions/someAction.js
JavaScript
exportasyncfunctionrun({ trigger }){
// This logs an object providing details about the trigger
An instance of your Gadget app's connections, which facilitate interactions with external systems. This object contains pre-configured clients for supported Gadget connections, such as Shopify, OpenAI and Sentry.
For instance, to update a product in Shopify:
api/models/someModel/actions/someAction.js
JavaScript
1exportasyncfunctionrun({ connections }){
2const productParams ={
3title:"New Product Title",
4price:"29.99",
5};
6
7// Creating a Shopify client and updating a product
If the record is a new record, this will persist the record and assign it an ID. If the record is an existing record, this will update the database with any changed values from the record.
save will validate the record before persisting it. save persists the record to the database using your app's Internal API.
Returns
Async function, which returns a Promise. Resolves to void. Any encountered validation errors will be thrown.
deleteRecord(record)
Deletes the given record from the database.
models/widget/actions/delete.js
JavaScript
import{ deleteRecord }from"gadget-server";
exportasyncfunctionrun({ record }){
awaitdeleteRecord(record);
}
delete removes the record from your database using your app's Internal API.
Returns
Async function, which returns a Promise. Resolves to void.
applyParams(params, record)
Sets incoming parameters onto a record object.
models/widget/actions/update.js
JavaScript
import{ applyParams }from"gadget-server";
exportasyncfunctionrun({ record }){
applyParams(record);
awaitsave(record);
}
applyParams will set any incoming parameters onto the record. This is useful for updating a record with the parameters from an action or similar call. applyParams does not persist the record -- it just mutates the in-memory record object.
Parameters
params - The data passed to an action from API calls, webhook events, or direct user inputs, which include the fields of a record.
record - Record to apply parameters to.
Returns
Returns void.
Background actions
enqueue(action, input, options)
Enqueues a model or global action to run in the background.
API/models/user/actions/status.js
JavaScript
1import{ enqueue }from"gadget-server";
2
3exportasyncfunctionrun({ record }){
4await api.enqueue(
5 api.someModelorGlobalAction,
6{},
7{id:"background-action-1",priority:"HIGH"}
8);
9}
Parameters
action - Any model or global action.
input - Parameters or data to pass to an action.
options (optional) - Options for governing how a background action is enqueued:
id - A unique identifier to use for the background action. Must be unique among all other background actions within its environment. If not set, a unique ID will be autogenerated and returned.
priority - How high to place this background action in its queue, HIGH priority actions will be executed before default priority actions, and those before LOW priority actions. If not set, the default priority will be used.
queue - A queue to put this background action in that limits the maximum concurrency of all actions in the queue. If not set, the action will go into the global queue, and won't be concurrency limited. For more info on queue options read the reference here.
startAt - The time to start running a background action. The time defined must be formatted as an ISO string.
Returns
Returns void.
queue
queue allows you to place the background action in a dedicated queue and also enables you to control the maximum concurrency of all actions in the queue.
JavaScript
1import{ enqueue }from"gadget-server";
2
3exportasyncfunctionrun({ record }){
4await api.enqueue(
5 api.someModelorGlobalAction,
6{},
7{
8queue:{
9name:"my-queue",
10maxConcurrency:4,
11},
12}
13);
14}
queue: The name of the queue.
maxConcurrency: The maximum concurrency of all actions in the queue. If not set, the default will be set to 1
retryPolicy
retryPolicy allows you to configure how fast and how many times to retry the background action if it fails.
JavaScript
1import{ enqueue }from"gadget-server";
2
3exportasyncfunctionrun({ record }){
4await api.enqueue(
5 api.someModelorGlobalAction,
6{},
7{
8retryPolicy:{
9retries:8,
10maxInterval:86400000,
11backoffFactor:2,
12initialInterval:1000,
13randomizeInterval:false,
14},
15}
16);
17}
retires: The maximum number of times to retry the operation if it keeps failing. The default is 6.
maxInterval: The maximum amount of time to delay a retry while exponentially backing off. The default is not set, so the retry can backoff indefinitely.
backoffFactor: The exponential backoff factor to use for calculating the retry delay for successive retries. Set this higher to delay longer. The default is 2.
initialInterval: How long to initially delay the first retry. The default is 1000 ms.
randomizeInterval: Randomizes the delays between attempts by multiplying with a factor between 1 to 2. The default is false.
Shopify
preventCrossShopDataAccess(params, record)
Enforce that the given record is only accessible by the current shop. For multi-tenant Shopify applications, this is key for enforcing data can only be accessed by the shop that owns it.
models/shopifyProduct/actions/update.js
JavaScript
1import{ applyParams, preventCrossShopDataAccess, save }from"gadget-server";
2
3exportasyncfunctionrun({ params, record, logger, api }){
4applyParams(params, record);
5awaitpreventCrossShopDataAccess(params, record);
6awaitsave(record);
7}
For existing records, this function verifies the record object has the same shopId as the shop in the current session, and throws if not.
For new records, this function sets the record's shopId to the current session's shopId.
Parameters
params - Incoming parameters, validated against the current shopId
record - Record to validate or set the shopId on
options:
shopBelongsToField: Picks which belongs to relationship on a model is used for cross-shop validation. Must be the api identifier of a belongs to relationship to the shopifyShip model. If there are multiple relationships to the shopifyShop model on the passed record, this is a required parameter.
Returns
Returns void. Throws if the record is not accessible by the current shop.
finishBulkOperation(record)
Updates the state of a bulkOperation record from Shopify when the operation completes.
models/shopifyBulkOperation/actions/complete.js
JavaScript
1import{
2 applyParams,
3 preventCrossShopDataAccess,
4 finishBulkOperation,
5 save,
6}from"gadget-server";
7
8exportasyncfunctionrun({ params, record, logger, api }){
stream - An AsyncIterable containing OpenAI response parts.
returns
A Readable stream with the transformed content from the input stream.
Action Contexts
Each Action and Global Action is passed a context object as its first and only argument. This context object contains all the inputs necessary for running an action, as well as some utilities.
The context object is usually destructured in the run or onSuccess function arguments with curly braces:
A connected, authorized instance of the generated API client for the current Gadget application. See the API Reference for more details on this object's interface
params
Record<string, any>
The incoming data from the API call invoking this action
record
GadgetRecord<Model>
The record this action is operating on. Only available in Model Actions, and not available in Global Actions.
session
Session
A record representing the current user's session, if there is one
config
Record<string, string>
An object of all the environment variables created in Gadget's Environment Variables editor
connections
Connections
An object containing client objects for all connections. Read the connections guide to see what each connection provides
An object describing the incoming HTTP request, if this action was triggered by an HTTP request
Exported Types
The gadget-server package contains TypeScript types specific to your application, generated from your app's models and fields. This gives great type safety where your actions and routes can import a specific type that describes the required inputs and output.
Actions
gadget-server exports a type for each Action's context argument, which is the data passed to the run or onSuccess function.
The context type is named <Action><Model>ActionContext, where <action> is the capitalized name of your action, and <model> is the capitalized name of your model. For example, if you have an action named create on a model named `user, you can import the type for that action like this:
gadget-server exports a type for each Global Action's context argument, which is the data passed to the run or onSuccess function.
The context type is named <Action>GlobalActionContext, where <action> is the capitalized name of your Global Action. For example, if you have a Global Action named flipWidgets, you can import the type for that action like this:
api triggers describe calls to your Gadget app's GraphQL API, like those made by the JS client or in the GraphQL playground.
An example API trigger
json
1{
2"type":"api",
3"mutationName":"updateWidget",
4"rootModel":"widget",
5"rootAction":"update",
6"rawParams":{
7"id":"123",
8"widget":{
9"title":"New Widget Title",
10"inventoryCount":10
11}
12}
13}
Properties
type: will always be set to "api"
mutationName: the string name of the mutation called in the API
rootModel: the API identifier of the Model the mutation was called on. Can be different than the root-level model when invoking Nested Actions. Is not set for Global Actions.
rootAction: the API identifier of the Action triggered by the mutation. Can be different than the root-level action when invoking Nested Actions.
rawParams: the params passed to this API call, including any data for nested actions if passed
scheduler trigger
scheduler triggers describe actions invoked by the built-in Scheduler within Gadget. No other data is currently passed with this type of trigger.
json
{
"type":"scheduler"
}
shopify_sync trigger
shopify_sync triggers describe actions run by Gadget's Shopify Sync, including daily syncs and manual syncs.
10"startReason": undefined // will be "scheduled" if Action ran via daily sync
11}
Properties
type: will always be set to "shopify_sync"
shopId: the identifier of the Shopify shop being synced
apiVersion: the version of the Shopify API being used for the sync
shopifyScopes: the available OAuth scopes of the Shopify shop being synced
syncId: the identifier of the sync record tracking the state of this sync (optional, only available if set)
syncSince: the specified date range of this sync (optional, only set if specified when the sync was started)
models: the list of model API identifiers that this sync will work on
force: indicates if this sync is being run in 'force' mode, which will always run actions even if the 'updated_at' timestamps match between Gadget and Shopify
startReason: the string describing the reason why this sync was started (optional, only set if specified when the sync began)
shopify_webhook trigger
shopify_webhook triggers describe actions that occur in response to Shopify webhooks, such as 'products/update' or 'orders/create'.
json
1// An example Shopify Webhook trigger
2{
3"type":"shopify_webhook",
4"topic":"products/update",
5"payload":{
6"id":788032119674292900,
7"title":"Example T-Shirt",
8"body_html":"An example T-Shirt",
9"vendor":"Acme",
10"product_type":"Shirts",
11"created_at":null,
12"handle":"example-t-shirt"
13// ... etc matching Shopify's format exactly
14},
15"shopId":"shop123",
16"retries":0
17}
Properties
type: will always be set to "shopify_webhook"
topic: the string representing the topic of the incoming webhook from Shopify, like products/update or orders/create
payload: the raw incoming payload from Shopify, which includes all the data sent by the webhook unchanged
shopId: the identifier for the Shopify store that received the webhook
retries: the number of times this webhook has been retried
shopify_oauth trigger
shopify_oauth triggers describe actions invoked during the installation of an app through the Shopify Partners connection process. No other data is currently passed with this type of trigger.
json
{
"type":"shopify_oauth"
}
shopify_admin trigger
shopify_admin triggers describe actions invoked during the installation of a Shopify app provisioned in the Shopify Admin. No other data is currently passed with this type of trigger.
json
{
"type":"shopify_admin"
}
RequestData
The RequestData type describes an incoming HTTP request being processed by an Action.
Note: The RequestData object is passed to Actions and Global Actions, and is a read-only view of the incoming request. This is different than the Request object passed to HTTP Route handlers which has more properties only available in HTTP routes.
Properties
ip: the requesting client's IP (also known as the x-forwarded-for header in other systems)
url: the requested URL (usually /api/graphql)
method: the HTTP request method, like GET, POST, etc
userAgent: the passed user agent string for this request
headers: a map of strings to strings or string arrays describing each incoming request header
id: a unique identifier assigned to this request by Gadget, used for logging and available in the x-request-id response header
JavaScript
exportasyncfunctionrun({ api, request,...rest }){
console.log(request.ip);// log the IP of the client making this request
}
Route handlers
Route context
All route handlers registered in HTTP Routes are passed a context object as their first and only argument:
Context key
Description
request
the Request object describing the incoming HTTP request
a connected, authorized instance of the generated API client for the current Gadget application. See the API Reference for more details on this object's interface.
applicationSession
a record representing the current user's session, if there is one.
applicationSessionID
the ID of the record representing the current user's session, if there is one.
connections
an object containing client objects for all connections. Read the connections guide to see what each connection provides.
logger
a logger object suitable for emitting log entries viewable in Gadget's Log Viewer.
config
an object of all the environment variables created in Gadget's Environment Variables editor.
currentAppUrl
the current url for the environment. e.g. https://my-app.gadget.app
request
The request object passed in the route context describes the incoming HTTP request, with properties for accessing the HTTP request headers, the request body, the matched route, and more. request is powered by Fastify, a high-performance HTTP framework for nodejs.
Request objects have the following fields:
FastifyRequest field
Description
query
the parsed query string from the incoming request, its format is specified by the route's querystringParser
body
the request payload, see Content-Type Parser for details on what request payloads Fastify natively parses and how to support other content types
params
the params matching the URL
headers
the headers getter and setter
method
the HTTP method for the route, like GET, POST, or DELETE
raw
the incoming HTTP request from Node core
id
the request ID
log
a logger instance for the incoming request
ip
the IP address of the incoming request
hostname
the host of the incoming request (derived from X-Forwarded-Host header when the trustProxy option is enabled). For HTTP/2 compatibility it returns :authority if no host header exists.
protocol
the protocol of the incoming request (will always be https on Gadget)
method
the method of the incoming request
url
the URL of the incoming request
routerMethod
the method defined for the router that is handling the request
routerPath
the path pattern defined for the router that is handling the request
is404
true if the request is being handled by a 404 error handler, false if it is not
socket
the underlying connection of the incoming request
routeSchema
the scheme definition set for the router that is handling the request
routeConfig
the route config object
routeOptions
the route option object passed when defining the route
bodyLimit
either the server-wide limit or route-specific limit on the size of the request body
url
the path of the URL to match this route
logLevel
log level defined for this route
version
a semver-compatible string that defines the version of the endpoint
exposeHeadRoute
creates a sibling HEAD route for any GET routes
prefixTrailingSlash
string used to determine how to handle passing / as a route with a prefix.
The reply object passed to each route in the context has functions for setting up and sending an HTTP response from your server for your route. The object is a FastifyReply object from Fastify, a high-performance HTTP framework for nodejs.
Reply objects have these functions and properties:
Reply property
Description
code(statusCode)
sets the status code
status(statusCode)
an alias for .code(statusCode)
statusCode
read and set the HTTP status code
header(name, value)
sets a response header
headers(object)
sets all the keys of the object as response headers
getHeader(name)
retrieve the value of an already set header
getHeaders()
gets a shallow copy of all current response headers
removeHeader(key)
remove the value of a previously set header
hasHeader(name)
determine if a header has been set
trailer(key, function)
sets a response trailer
hasTrailer(key)
determine if a trailer has been set
removeTrailer(key)
remove the value of a previously set trailer
type(value)
sets the header Content-Type
redirect([code,] dest)
redirect to the specified URL with an optional status code. If not provided, the status code defaults to 302
callNotFound()
invokes the custom not found handler
serialize(payload)
serializes the specified payload using the default JSON serializer or using the custom serializer (if one is set) and returns the serialized payload
serializer(function)
sets a custom serializer for the payload
send(payload)
sends the payload to the user, could be a plain text, a buffer, JSON, stream, or an Error object
sent
a boolean value that you can use if you need to know if send has already been called
LoggerInstance is a high performance alternative to console.log which is optimized for use in production. console.log logs will still appear in your Log Viewer but are not recommended for use in production.
The default log levels (and associated log functions) are trace, debug, info, warn, error, and fatal.
An object can optionally be supplied as the first parameter to log messages. Each key and value of the object is stringified and written to your application's logs as JSON.
JavaScript
logger.info({value:{foo:"bar"}});
Log calls at any level can also pass Error objects to get an easy-to-digest log entry in the Log Viewer for the error, including its stack trace and any other associated details. To log Error objects, pass the object at the error key of the structured data: