Migrate to GraphQL from REST
The REST Admin API is a legacy API as of October 1, 2024. All apps and integrations should be built with the GraphQL Admin API. Read on to learn how to migrate from the REST Admin API to the GraphQL Admin API.
When you begin using GraphQL, you need to change how you think about retrieving and working with data. This guide describes some of the key considerations when migrating from REST to GraphQL. It's meant for app developers who are primarily using REST in their apps.
Anchor to Finding GraphQL objects and operationsFinding Graph QL objects and operations
Many REST Admin API resources and endpoints have a direct equivalent in GraphQL. Most GET
, PUT
, POST
and DELETE
requests in REST have an equivalent query or mutation in GraphQL.
However, some REST resources and operations might not have an exact GraphQL equivalent. This is because Shopify GraphQL APIs are built to leverage the efficiencies of GraphQL, newer platform features are exposed only in GraphQL, and some enhancements to the Shopify data model are reflected in only the GraphQL schema. The functionality included in one REST POST
, PUT
, or DELETE
operation is often split between multiple GraphQL mutations.
You can explore the GraphQL Admin API reference and build your mutations using the GraphiQL explorer to identify which mutation is appropriate for your use case.
Anchor to Example: Direct equivalent in GraphQLExample: Direct equivalent in Graph QL
Retrieving information about a single customer is very similar in REST and GraphQL.
In this example, the GraphQL query retrieves all of the same information as is returned in the REST GET request. However, some of the field names and data structures are slightly different from their REST equivalents.
In GraphQL, you can optimize your query to retrieve only the fields that you need.
REST
Endpoint
JSON response
GraphQL
Endpoint
Graphql query
JSON response
Anchor to Example: REST functionality split in GraphQLExample: REST functionality split in Graph QL
In the following example, using REST you can use the generic product update request to delete an image from a product. This functionality isn't included in the GraphQL Admin API’s productUpdate
mutation. Instead, to delete images, you need to use the productDeleteMedia
mutation.
REST
Endpoint
Request body
JSON response (truncated)
GraphQL
Endpoint
GraphQL mutation
JSON response
Anchor to Finding required access scopesFinding required access scopes
After you've found an equivalent GraphQL object, you'll need to determine if your app has the appropriate access scopes to work with the object and its associated queries and mutations. Access scopes are defined at the top of the page for each type in the GraphQL Admin API reference.
You can check your app’s granted access scopes using the appInstallation
query in the GraphQL Admin API.
Anchor to Translating IDs from REST to GraphQLTranslating IDs from REST to Graph QL
REST and GraphQL use different formats for resource and object IDs. If you use stored IDs to retrieve resources in the REST Admin API, then you need to retrieve and store the equivalent GraphQL API global ID (GID) before you can run the corresponding queries and mutations in GraphQL APIs.
Most REST responses include the admin_graphql_api_id
property. You can use the ID in this property to directly query the equivalent object in GraphQL.
You can also view some common examples of GraphQL GIDs in our GID documentation.
The admin_graphql_api_id
property is returned only to apps. It isn't included in responses that are viewed in a web browser.
Anchor to Example: Retrieve a GraphQL object ID from RESTExample: Retrieve a Graph QL object ID from REST
The following example retrieves a product variant ID in REST, and then uses the admin_graphql_api_id
property to query the equivalent product variant ID in GraphQL.
REST
Endpoint
JSON response (truncated)
GraphQL
Endpoint
GraphQL query
JSON response
Anchor to Resources that don't return an Admin GraphQL API IDResources that don't return an Admin Graph QL API ID
In some cases, a resource might not return an admin_graphql_api_id
. This ID might not be available for several reasons. For example, a resource might not have an exact equivalent GraphQL object. In this case, you can determine the appropriate object to use, and then use examples in the GraphQL Admin API reference or query the object in the GraphiQL explorer to learn about the ID format.
Anchor to Anatomy of a GraphQL IDAnatomy of a Graph QL ID
GraphQL ID generation is implementation dependent, and doesn't follow any convention other than being a URI. There is no guarantee that GraphQL IDs will follow the structure gid://shopify/{resource}/{rest_id}
as in the previous example, so you shouldn't generate IDs programmatically. Always treat the admin_graphql_api_id
string as an opaque ID.
The following example shows how the admin_graphql_api_id
property doesn't always follow an expected structure:
Example
Endpoint
JSON response
Anchor to Implementing and updating paginationImplementing and updating pagination
In REST, you can paginate data using query parameters. Using the limit
parameter, you can split the total number of entries into manageable groups:
To get the next page of results, you can make a request to the URL stored in the Link
header of the last response:
In GraphQL, you can apply similar concepts using cursor-based pagination. When querying a connection in GraphQL, you need to provide the first
or last
argument, which specifies the number of items that you want returned from the beginning or the end of the set. This is equivalent to the limit
parameter in REST.
A connection is a GraphQL type that's used to retrieve a list of nodes. A node is an individual item or data object in the list, and represents the data that you're querying for. For example, the ProductConnection
finds all the edges that connect the query root to a Product
node.
You can query the cursor
field to get a reference to the position of a node in a connection, and use that reference to obtain the next set of items. The cursor
field in GraphQL is equivalent to the page_info
parameter in REST.
You can also query the pageInfo
object in GraphQL to determine if there are any more pages to request. The fields hasNextPage
and hasPreviousPage
are boolean fields that indicate whether you can paginate forwards or backwards. Depending on the direction that you're paging in, you can use the relevant field to determine when you've reached the end of the list. For example, if you're paginating forward using the first
argument, then you've reached the end of the list when hasNextPage
is false
.
You can retrieve up to 250 resources in a single request. If you need to retrieve larger volumes of data, then you can perform a bulk query operation. A bulk query operation lets you asynchronously fetch all of the items in a list using as little as one query, avoiding the need to paginate results and the risk of your requests being throttled.
Anchor to ExampleExample
The following example shows how to query the first three products and determine whether you can paginate forward. The JSON response returns the product IDs, titles, and cursor IDs, and indicates that you can paginate forward.
Example
Endpoint
GraphQL query
JSON response
You can provide the after
argument with the last cursor from the response to request the next set of data:
Example
Endpoint
GraphQL query
JSON response
Anchor to Understanding error handlingUnderstanding error handling
In GraphQL, you can't always rely on HTTP status codes to determine whether a query or mutation completed without errors. In cases that would typically produce 4xx
or 5xx
errors in REST, GraphQL might return a 200 OK
status with additional error information in its response.
The 4xx
and 5xx
errors occur infrequently. They're often related to network communications, your account, or an issue with Shopify’s services.
To learn about the possible response codes and what they mean, refer to Shopify API response status and error codes.
Anchor to Query errorsQuery errors
If a query results in an error, then an errors
object is returned. The object contains additional detail that can help you debug your operation.
Example
Endpoint
GraphQL query
JSON response - 200 OK
Anchor to Mutation errorsMutation errors
The response for mutations also can return additional detail to help debug your mutation. To access this information, you must request the userErrors
field.
Example
Endpoint
GraphQL mutation
JSON response - 200 OK
Anchor to Updating your error handlingUpdating your error handling
The following is a basic JavaScript example of how you might handle an error in REST, and how your error handling might be updated to parse errors returned in GraphQL responses with a status of 200 OK.
Handling errors in REST
Handling errors in GraphQL
Anchor to Understanding rate limitingUnderstanding rate limiting
To ensure the Shopify platform remains stable and fair for everyone, both the REST and GraphQL Admin APIs are rate-limited. However, these two APIs use a different rate limiting approach.
Anchor to RESTREST
The REST Admin API is governed by request-based limits. It provides credits that clients spend every time they make a request, and those credits are refilled every second. This allows clients to keep a request pace that never limits the API usage (two requests for each second) and makes occasional request bursts when needed (making 10 requests for each second).
However, the request-based model has the following limitations:
- Clients use the same amount of credits regardless, even if they don’t need all the data in an API response.
POST
,PUT
,PATCH
andDELETE
requests produce side effects that demand more load on servers thanGET
requests, which only reads existing data. Despite the difference in resource usage, all these requests consume the same amount of credits in the request-based model.
Anchor to GraphQLGraph QL
GraphQL addresses some limitations of common methods that are typically used in REST APIs.
The GraphQL Admin API uses a calculated cost query method for rate limiting. By default, in a calculated query cost method, clients receive 50 points per second up to a limit of 1,000 points.
The main difference from the REST request-based model is that every GraphQL request has a different cost.
Anchor to Calculating costsCalculating costs
The best way to determine the true cost of a query or mutation is to run it. In the following mutation example that creates a metaobject, the JSON response includes information about the total mutation cost and the client’s current quota under the extensions field. You can include an Shopify-GraphQL-Cost-Debug=1
header to receive a more detailed breakdown of the query or mutation cost.
You can use the currentlyAvailable
and restoreRate
fields returned in the throttleStatus
object to understand how many points you have available and how quickly they'll refill. This also helps you to adjust if a client has a different bucket size or restore rate, or if the global allocation changes in future.
Example
Endpoint
GraphQL mutation
JSON response
Anchor to Throttled requestsThrottled requests
In REST, if an app reaches an API rate limit, then it receives a 429 Too Many Requests
response and a message that a throttle has been applied.
In GraphQL, if an app reaches an API rate limit, then it receives a 200 OK
response, but the response body contains an error with a message that a throttle has been applied. You can handle for these throttled requests the same way that you handle for other errors returned by GraphQL.
Example response
Anchor to Optimizing your requestsOptimizing your requests
Depending on your use case, you might be able to further optimize your GraphQL requests. Optimizing requests improves the performance of your app by reducing the number of calls that need to be made to the GraphQL endpoint, and helps you to avoid being throttled by sending fewer queries or queries with a lower cost.
You can investigate the following optimization opportunities:
- Combine multiple REST requests into a single GraphQL query: Retrieve all of the information about a single object in a single request, rather than chaining multiple requests together.
- Request only the data that you need: Simplify your queries and mutations by requesting only information that your app is using.
- Use the best mutation: Avoid round trips and chaining by using a mutation that's tailored to your use case.
- Use bulk operations: Fetch or upload data in bulk to make working with large volumes of data easier.
Anchor to Combine multiple REST requests into a single GraphQL queryCombine multiple REST requests into a single Graph QL query
In GraphQL, you can use connections to get information about related objects with a single request.
For example, in the case of an order, you might want to know the total price, the customer's name, metafields, and the title of other variants belonging to the product in the order.
Using REST, you need to make a request to the following endpoints and filter out unnecessary data:
/orders/{order_id}.json
/products/{product_id}/variants.json
/customers/{customer_id}/metafields.json
Using GraphQL, you can make a single request using connections to get the desired data:
Example
Endpoint
GraphQL query
JSON response
Anchor to Request only the data you needRequest only the data you need
To avoid over-fetching, request only the fields that your app is using in your queries and mutations. This reduces the payload size, reducing bandwidth usage and improving performance.
For example, when you request a customer using REST, the response contains over 60 fields:
REST
Endpoint
JSON response
If you only need to retrieve customer contact and address information, then you can build your query to retrieve only this information:
GraphQL
Endpoint
GraphQL query
JSON response
Anchor to Use the best mutationUse the best mutation
In some cases, you can lessen the number of calls that you need to make by choosing a mutation that's tailored for your use case.
For example, if you wanted to make a copy of a product using a new name, then you could query for the product to be duplicated using a product
query, edit the product fields, and then create a new product using a productCreate
mutation. However, the GraphQL Admin API provides a productDuplicate
mutation, which allows you to duplicate the product and update key information including the title and status, avoiding a round trip and lessening the amount of data that needs to be sent to and retrieved from Shopify.
If you don't need to use the duplicated product right away, then you also have the option to use productDuplicateAsyncV2
to duplicate the product asynchronously.
Anchor to Use bulk operationsUse bulk operations
If you need to import or export large volumes of data, then you can perform a bulk operation. Bulk operations lessen complexity by reducing the number of requests that you need to make, avoiding throttling and considerations such as pagination.
For example, if you retrieved all products in REST from the /products.json
endpoint, then you can instead use bulkOperationRunQuery
.
Learn more about bulk queries and mutations.
Anchor to Understanding library supportUnderstanding library support
Many API client libraries that you might use to call the Shopify Admin API support both REST and GraphQL.
-
Official Shopify API libraries:
-
Some third-party Admin API libraries
However, you need to make updates to your code that uses these libraries. You might have to perform some or all of the following tasks:
-
Switching from a REST client to a GraphQL client
-
Changing the API endpoint
-
Updating the request type
-
Adding your query or mutation and specifying the fields to return
-
Destructuring or digging into the response
For examples of updating your implementation using some commonly used libraries, refer to Updating API calls in your app.
Anchor to Next stepsNext steps
Learn how to use GraphQL APIs with our .dev Assistant, Shopify Dev Assistant Visual Studio Code extension, and how-to guides that cover different use cases:
Generate GraphQL operations, convert REST requests to GraphQL operations, and get interactive help with Shopify's AI-powered assistant.
Trained on Shopify data for high accuracy.
Access AI-powered Shopify development help directly within Visual Studio Code, with automatic GraphQL query execution and GraphiQL integration.
Trained on Shopify data for high accuracy and seamlessly integrates with your local development workflow.
Learn how to create and manage different types of discounts with the GraphQL Admin API.
Learn how to edit orders that a Shopify channel creates, such as Shopify Point of Sale (POS), Online Store, or draft orders, or orders that the app creates through the GraphQL Admin API.
Learn how to manage different types of media associated with products using the GraphQL Admin and Storefront APIs.
Learn how to manage different types of media associated with product variants using the GraphQL Admin API.
Learn how to maintain accurate inventory quantities and transition products to different inventory states.
Learn how to manage returns using the GraphQL Admin API.
Learn how to manage metafields using the GraphQL Admin API.