Update API calls in your app
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.
Many API client libraries that you might use to call the Shopify Admin API support both REST and GraphQL. However, you need to make updates to your code that uses these libraries. Some updates that you need to make might include the following:
- Switching from a REST client to a GraphQL client
- Changing the API endpoint
- Updating the method
- Adding your query or mutation and specifying the fields to return
- Destructuring or digging into the response
You don't need to update your authentication or session handling to update from REST to GraphQL.
Use the following examples to understand the changes that you need to make for each API library.
This guide doesn't explain all of the changes that you need to make to your app to use GraphQL instead of REST. For example, you need to update your error handling and pagination logic. Learn more about considerations when migrating from REST to GraphQL.
Anchor to shopify-api-jsshopify-api-js
The following examples show you how to update your calls to GraphQL when reading or writing data using the shopify-api-js library.
Anchor to Reading dataReading data
The following requests retrieve information about a product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
Update | Description |
---|---|
Change the client type | Remix: Instead of creating an Non-Remix: Instead of creating a |
Change the method | Instead of using the get method on the REST client or the find , all , or count method on the resource class, use the query method on the GraphQL client. |
Add a query | Pass a query to the client, requesting the information that you want to retrieve. Instead of specifying the path to the resource (like If you're retrieving a resource by its ID, then use the GraphQL API global ID (GID) for the resource (like |
Destructure the response | GraphQL responses are typically nested within a data object. The structure of the data mirrors the structure of the query. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using dot notation ( |
Read
REST
const {admin, session} = await authenticate.admin(request);
const product = await admin.rest.resources.Product.find({
session,
id: 1234,
});
console.log(product);
const { admin } = await authenticate.admin(request);
const response = await admin.rest.get({
path: "products/1234",
});
const body = await response.json();
console.log(response.headers, body);
const product = await shopify.rest.Product.find({
session,
id: 1234,
});
console.log(product);
const client = new shopify.clients.Rest({
session,
});
const response = await client.get({
path: 'products/1234',
});
console.log(response.headers, response.body);
GraphQL
const {admin} = await authenticate.admin(request);
// Create a GraphQL client instead of creating a REST client
// or using REST resource classes
//
// Pass a GraphQL mutation in the request body
// instead of using REST resources or passing a path and data to the post method
const response = await admin.graphql(
`#graphql
query {
product(id: "gid://shopify/Product/1234") {
title
description
}
}`,
);
// Destructure the response
const body = await response.json();
const product = body.data?.product;
// Create a GraphQL client instead of creating a REST client
// or using REST resource classes
const client = new shopify.clients.Graphql({
session,
});
// Pass a GraphQL query in the request body
// instead of using REST resources or passing a path
// Use a GID instead of a simple ID
const response = await client.query({
data: `{
product(id: "gid://shopify/Product/1234") {
title
description
}
}`,
});
// Destructure the response
const product = response.body?.data.product;
console.log(product);
Anchor to Writing dataWriting data
The following requests create a new product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
Update | Description |
---|---|
Change the client type | Remix: Instead of creating an Non-Remix: Instead of creating a |
Change the method | Instead of using the post , put , or delete method on the REST client, or the save or delete method on the resource class, use the query method on the GraphQL client. |
Add a mutation | Instead of specifying the path to the resource (like |
Destructure the response | GraphQL responses are typically nested within a data object, and the structure of the data often mirrors the structure of the mutation. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using dot notation ( |
Read userErrors | Extract the userErrors array from the response. If the mutation wasn't completed, then this information is returned in this array. Learn about how error handling differs in GraphQL. |
Write
REST
const { admin, session } = await authenticate.admin(request);
const product = new admin.rest.resources.Product({ session });
product.title = "My new product";
await product.save({
update: true,
});
const {admin} = await authenticate.admin(request);
const response = await admin.rest.post({
path: 'products',
data: {
product: {
title: "My new product"
}
}
});
const body = await response.json();
console.log(response.headers, body);
const product = new shopify.rest.Product({session: session});
product.title = "My new product";
await product.save({
update: true,
});
const client = new shopify.clients.Rest({
session,
});
const response = await client.post({
path: 'products',
data: {
product: {
title: "My new product"
}
}
});
console.log(response.headers, response.body);
GraphQL
const {admin} = await authenticate.admin(request);
// Create a GraphQL client instead of creating a REST client
// or using REST resource classes
//
// Pass a GraphQL mutation in the request body
// instead of using REST resources or passing a path and data to the post method
const response = await admin.graphql(
`#graphql
mutation {
productCreate(input: {title: "My new product"}) {
product {
id
}
}
}`,
);
// Destructure the response
const body = await response.json();
const product = body.data?.productCreate?.product;
// Create a GraphQL client instead of creating a REST client
// or using REST resource classes
const client = new shopify.clients.GraphQL({
session,
apiVersion: ApiVersion.October23,
});
// Pass a GraphQL mutation in the request body
// instead of using REST resources or passing a path and data to the post method
const response = await client.query({
data: `
mutation {
productCreate(input: { title: "My new product" }) {
product {
id
title
}
userErrors {
field
message
}
}
}`,
});
// Destructure the response
const data = response.body?.data;
const {product, userErrors} = data?.productCreate;
console.log(product);
console.log(userErrors);
Anchor to shopify-api-rubyshopify-api-ruby
The following examples show you how to update your calls to GraphQL when reading or writing data using the shopify-api-ruby library.
Anchor to Reading dataReading data
The following requests retrieve information about a product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
Update | Description |
---|---|
Change the client type | Instead of creating a shopify.clients.Rest client or using REST resource classes like shopify.rest.Product.find , create a shopify.clients.GraphQL client. |
Change the method | Instead of using the get method on the REST client or the find , all , or count method on the resource class, use the query method on the GraphQL client. |
Add a query | Pass a query to the client, requesting the information that you want to retrieve. Instead of specifying the path to a resource (like If you're retrieving a resource by its ID, then use the GraphQL API global ID (GID) for the resource (like |
Destructure the response | GraphQL responses are typically nested within a data object. The structure of the data mirrors the structure of the query. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using bracket notation. In the provided Ruby example, the product data is accessed with |
Read
REST
product = ShopifyAPI::Product.find('product-id')
puts product.attributes
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
response = client.get(path: "products/1234")
some_function(response.body)
GraphQL
Anchor to Writing dataWriting data
The following requests create a new product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
Update | Description |
---|---|
Change the client type | Instead of creating a ShopifyAPI::Clients::Rest::Admin client or using REST resource classes like ShopifyAPI::Product , create a ShopifyAPI::Clients::Graphql::Admin client. |
Change the method | Instead of using the post , put , or delete method on the REST client, or the save or delete method on the resource class, use the query method on the GraphQL client. |
Add a mutation | Instead of specifying the path to the resource (like |
Destructure the response | GraphQL responses are typically nested within a data object, and the structure of the data often mirrors the structure of the mutation. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using dot notation ( |
Read userErrors | Extract the userErrors array from the response. If the mutation wasn't completed, then this information is returned in this array. Learn about how error handling differs in GraphQL. |
Write
REST
product_properties = {
title: "My new product"
}
product = ShopifyAPI::Product.new(from_hash: product_properties)
product.save!
# Create a new client.
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
body = {
product: {
title: "My new product",
}
}
client.post({
path: "products",
body: body,
});
GraphQL
Anchor to Node Fetch / AxiosNode Fetch / Axios
The following examples show you how to update your calls to GraphQL when reading or writing data using the Node Fetch or Axios libraries.
Anchor to Reading dataReading data
The following requests retrieve information about a product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
Update | Description |
---|---|
Change the endpoint | Instead of a resource-specific endpoint (/products/1234.json ), use the generic GraphQL endpoint for the store. Information about the resource that you want to retrieve is passed in the request body. |
Change the method | Instead of using GET , use POST for all requests. |
Add a query | In the request body, query the resource (for example, Instead of using a simple ID ( Specify the fields that you want to return in the request body. |
Destructure the response | GraphQL responses are typically nested within a data object. The structure of the data mirrors the structure of the query. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using dot notation ( |
Read
REST
(async () => {
const url = 'https://shop.myshopify.com/admin/api/2023-10/products/1234.json';
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
}
}
const response = await fetch(url, options);
const data = await response.json();
console.log(data);
})();
(async () => {
const axios = require('axios');
const options = {
url: 'https://shop.myshopify.com/admin/api/2023-10/products/1234.json',
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
}
}
const { data: { product } } = await axios(options);
console.log(product);
})();
GraphQL
(async () => {
// Update to the GraphQL endpoint
const url = 'https://shop.myshopify.com/admin/api/2023-10/graphql.json';
// Add a query with the fields that you want to retrieve
// Use a GID instead of a simple ID
const query = {
query: `
{
product(id: "gid://shopify/Product/1234") {
title
description
}
}`
};
const options = {
// Use POST instead of GET
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
// Pass the query in the request body
body: JSON.stringify({
query: query
})
}
const response = await fetch(url, options);
// Destructure the response
const { data: { product } } = await response.json();
console.log(product);
})();
(async () => {
const axios = require('axios');
// Update to the GraphQL endpoint
const options = {
url: 'https://shop.myshopify.com/admin/api/2023-10/graphql.json',
// Use POST instead of GET
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
// Pass the query in the request body
// Add a query with the fields that you want to retrieve
// Use a GID instead of a simple ID
data: JSON.stringify({
query: `
query product($id: ID!) {
product(id: $id) {
title
description
}
}`,
variables: {
id: "gid://shopify/Product/1234"
}
})
}
// Destructure the response
const { data: { data: { product } } } = await axios(options);
console.log(product);
})();
Anchor to Writing dataWriting data
The following requests create a new product. To convert the REST version of this request to GraphQL, you need to make the following changes in your code.
The same changes need to be made when updating from a POST
, PUT
, or DELETE
REST call.
Update | Description |
---|---|
Change the endpoint | Instead of a resource-specific endpoint (/products/1234.json ), use the generic GraphQL endpoint for the store. The details for the update that you want to make is now part of a GraphQL mutation that's passed in the request body. |
Change the method | If you're using a PUT or DELETE method, then update the method to POST . |
Add a query | Add a GraphQL mutation in the request body. In this example, we're creating a new product. |
Add query variables | Pass the details for the resource that you want to create or update as query variable. If you're updating or deleting a resource, then instead of using a simple ID ( |
Destructure the response | GraphQL responses are typically nested within a data object. The structure of the data mirrors the structure of the query. To make the data easier to work with, destructure the object that's returned. You can also access properties of the object using dot notation ( |
Read userErrors | Extract the userErrors array from the response. If the mutation wasn't completed, then this information is returned in this array. Learn about how error handling differs in GraphQL. |
Write
REST
(async () => {
const url = 'https://your-store-name.myshopify.com/admin/api/2023-10/products.json';
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
body: JSON.stringify({product: {title: "My new product"}})
}
const response = await fetch(url, options);
const { product } = await response.json();
console.log(product);
})();
(async () => {
const axios = require('axios');
const options = {
url: 'https://shop.myshopify.com/admin/api/2023-10/products.json',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
data: JSON.stringify({
product: {
title: "My new product"
}
})
}
const response = await axios(options);
console.log(response);
})();
GraphQL
(async () => {
// Update to the GraphQL endpoint
const url = 'https://your-store-name.myshopify.com/admin/api/2023-10/graphql.json';
// Add a mutation and include the fields that you want to be returned in the response
const query = `
mutation productCreate($input: ProductInput!) {
productCreate(input: $input) {
product {
id
}
userErrors {
field
message
}
}
}`
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
// Pass the query in the request body
// Pass the content for the new object as input variables
body: JSON.stringify({
query: query,
variables: {
input: {
title: "My new product"
}
}
})
}
const response = await fetch(url, options);
// Destructure the response
const { data: { productCreate: { product, userErrors } } } = await response.json();
console.log(product);
// Read errors from the response
console.log(userErrors);
})();
(async () => {
const axios = require('axios');
// Add a mutation and include the fields that you want to be returned in the response
const query = `
mutation productCreate($input: ProductInput!) {
productCreate(input: $input) {
product {
id
title
}
userErrors {
field
message
}
}
}`;
// Update to the GraphQL endpoint
const options = {
url: 'https://shop.myshopify.com/admin/api/2023-10/graphql.json',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Access-Token': 'YOUR-ACCESS-TOKEN'
},
// Pass the query in the request body
// Pass the content for the new object as input variables
data: {
query: query,
variables: {
input: {
title: "My new product"
}
}
}
}
// Destructure the response
const { data: { data: { productCreate: { product, userErrors } } } } = await axios(options);
console.log(product);
// Read errors from the response
console.log(userErrors);
})();