Function input and output
Shopify Functions request an input against the schema of the specific Function API schema. Function API schemas are based on the Cart API. The output is also defined by the same Function API schema. The output is a declarative object which represents operations for Shopify to execute.
Shopify passes input as JSON to your function via
STDIN, and your function writes output to Shopify via
STDOUT. See the WebAssembly API for details.
You can specify what input your function needs using an input query. For example, the structure of the JSON in the input example matches the shape of the following query:
When you create a function, an
input.graphql file is generated at the root of your project directory. You can edit the query to request the exact data you need, which results in a more performant function. The query is executed against the specific Function input API, in the context of the current execution.
Input exampleAnchor link to section titled "Input example"
The following example shows an input that retrieves a customer's email along with the payment methods:
Each Function API specifies the shape of the function's output using an object with the name
FunctionResult. For example, there's a
FunctionResult definition for the Order Discount API.
If a function discounts an order by $50.00, then it could return the following output:
Using metafields with input queriesAnchor link to section titled "Using metafields with input queries"
To make your code reusable, you can replace hard-coded variables in your function with metafield values. Using metafields enables merchants and staff to customize your function by entering values and options in interfaces provided by your app.
How it worksAnchor link to section titled "How it works"
Shopify Functions belong to and can affect the behavior of objects in the Shopify data model. The object associated with a function is known as the function owner. For example, the owner of a Discount API function is a discount.
You use App Bridge to create merchant UIs for managing function owners and their metafields. Then, you use input queries to provide the metafields as input to your function.
Create your merchant interfaceAnchor link to section titled "Create your merchant interface"
When implementing a function, you must configure it with routes in your application which merchants will use to create and edit the function owner, such as a discount.
You must configure the following properties in your function settings. The default path for both properties is the root directory of your app (
||The route to create a new function owner.||
||The route to edit the function owner.||
The following example shows the properties in the
Dynamic ID valuesAnchor link to section titled "Dynamic ID values"
If you specify the
:functionId in the
ui.paths properties in
shopify.function.extension.toml, then the URL is updated with the following values:
The ID values are needed as input to the create, update, and delete mutations for your customizations. By using dynamic IDs, you can avoid managing hardcoded values in your app.
Merchant experienceAnchor link to section titled "Merchant experience"
Use App Bridge and Polaris to create a seamless merchant experience within the Shopify admin. You can use the GraphQL Admin API to create and update your function owner and its metafields. Metafields are supported on all function owner types, and can be used to store custom values for your function logic.
The following is an example of a mutation that would set metafields on a discount function owner, when implementing a Discount API function.
Read metafields with input queriesAnchor link to section titled "Read metafields with input queries"
All Function APIs provide access to the function owner, and its metafields, as part of their GraphQL schema. This means that you can access the metafield values set by merchants using input queries, and use those values in your function's logic.
The following is an example of an input query that would retrieve a metafield on a discount function owner, when implementing a Discount API function.
GraphQL schemaAnchor link to section titled "GraphQL schema"
Each Function API has a GraphQL schema representation, which you can use to improve your development workflow. For example, a GraphQL schema can be used with:
On creation, each function includes a copy of the GraphQL schema in the
Generating the latest schemaAnchor link to section titled "Generating the latest schema"
If you are using an unstable API version, then the GraphQL schema might have changed since you created the function or last generated the schema. If you change your target API version, then the Function API schema might have changed between versions. To generate the latest GraphQL schema for your function, use the
generate schema command. This command outputs the latest schema based on your function's API type and version to stdout. This output may be saved to a file or piped to a code generation tool.
To overwrite your function's
schema.graphql file with a newly generated version, run the following command from your function directory:
Input query limitationsAnchor link to section titled "Input query limitations"
The following limitations apply to input queries:
- The maximum size for an input query, excluding comments, is 3000 bytes.
- Metafields with values exceeding 1 kB in size will not be returned.
Function input queries can have a maximum calculated query cost of 30. The following table describes the input query field costs for functions:
Field Cost value Any field that returns a
Metafieldobject (For example,
3 Any field on a
Metafieldobject (For example,
3 Other leaf nodes (For example,
Best practicesAnchor link to section titled "Best practices"
This section provides some best practices for using metafields for function input.
Use your app name as your metafield namespaceAnchor link to section titled "Use your app name as your metafield namespace"
To avoid conflicts with other apps, use a derivative of your app's name for your metafield namespace.
For example, if your app name is Discounts Plus, then use a metafield namespace such as
Use JSON metafields for complex configurationsAnchor link to section titled "Use JSON metafields for complex configurations"
Metafields support many types of data, but functions will often require nested and/or repeating data structures. Using a single JSON metafield can simplify the management and querying of your configuration.
Manage configuration changes with new metafieldsAnchor link to section titled "Manage configuration changes with new metafields"
If you need to make breaking changes to your function configuration data, then you can implement the Parallel Change (Expand and Contract) pattern using additional metafields:
- Update your function's logic to simultaneously read configuration from your existing and new metafields, preferring the newer data, if present.
- Change your function UI to simultaneously update both your existing and new metafields.
- Use the GraphQL Admin API to migrate existing data from your old metafields to your new metafields.
- After you've finished the migration, remove any UI and function logic for your old metafields.
- Use the GraphQL Admin API to remove your old metafields.