ShopifyAPI::GraphQL::Request
Small class to simplify the writing and handling of GraphQL queries and mutations for the Shopify Admin API. Comes with built-in retry, pagination, error handling, and more!
Usage
It's recommended to organize queries and mutations by subclassing ShopifyAPI::GraphQL::Request:
require "shopify_api/graphql/request"
class ShopifyProduct < ShopifyAPI::GraphQL::Request
# Define your queries/mutations
FIND =<<-GQL
query($id: ID!) {
product(id: $id) {
id
title
descriptionHtml
}
}
GQL
UPDATE =<<-GQL
mutation($product: ProductUpdateInput!) {
productUpdate(product: $product) {
product {
id
title
descriptionHtml
}
userErrors {
field
message
}
}
}
GQL
LIST <<-GQL
query($after: String) {
products(first: 25 after: $after) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
title
descriptionHtml
}
}
}
}
GQL
def find(id)
execute(FIND, :id => gid::Product(id)).dig(:data, :product)
end
def update(id, changes)
execute(UPDATE, :product => changes.merge(:id => gid::Product(id))).dig(:data, :product_update, :product)
end
def list
paginate(LIST) { |page| yield page.dig(:data, :products, :edges) }
end
end
Then use it:
shopify = ShopifyProduct.new("a-shop", token)
begin
product = shopify.find(123)
p product[:id]
p product[:description_html]
rescue ShopifyAPI::GraphQL::Request::NotFoundError => e
warn "Product not found: #{e}"
end
begin
product = shopify.update(123, :description_html => "Something amaaaazing!")
p product[:id]
p product[:description_html]
rescue ShopifyAPI::GraphQL::Request::UserError => e
warn "User errors:"
e.errors { |err| warn err["field"] }
end
begin
shopify.list(123) do |node|
product = node[:node]
p product[:id]
p product[:description_html]
end
rescue ShopifyAPI::GraphQL::Request::NotFoundError => e
warn "Request failed: #{e}"
end
Subclasses have access to the following methods:
#execute- Execute a query or mutation with the provided arguments#paginate- Execute a query with pagination; without a block a lazy enumerator (Enumerator::Lazy) is returned#gid- Used for Global ID manipulation (an instance ofTinyGID)#gql- The underlying GraphQL client (an instance ofShopifyAPI::GraphQL::Tiny)
#execute and #paginate also:
- Automatically retry failed or rate-limited requests
- Accept
snake_caseSymbolkeys - Return a
Hashwithsnake_caseSymbolkeys - Raise a
UserErrorwhen a mutation's response containsuserErrors - Raise a
NotFoundErrorwhen a query's result cannot be found
Both of these are small wrappers around the equivalent methods on ShopifyAPI::GraphQL::Tiny.
For more information see its documentation on retries.
With the exception of retry, most defaults can be disabled per instance or per execution:
class ShopifyProduct < ShopifyAPI::GraphQL::Request
def initialize(shop, token)
super(shop, token, :raise_if_not_found => false, :raise_if_user_errors => false, :snake_case => false)
end
def find(gid)
execute(QUERY, :raise_if_not_found => true)
end
end
Disabling retry must be done per instance.
Setting the GraphQL API Version
Pass the desired version to Request's constructor:
class ShopifyProduct < ShopifyAPI::GraphQL::Request
def initialize(shop, token)
super(shop, token, :version => "2026-01")
end
end
Making Requests Without Subclassing
Of course you can make requests directly on an instance of ShopifyAPI::GraphQL::Request:
require "shopify_api/graphql/request"
request = ShopifyAPI::GraphQL::Request.new("a-shop", token)
begin
product = request.execute(query, :id => "gid://shopify/Product/123").dig(:data, :product)
p product[:title]
p product[:description_html]
rescue ShopifyAPI::GraphQL::Request::NotFoundError => e
p e
end
And mutations:
begin
product = request.execute(mutation, :id => "gid://shopify/Product/123", :title => "Foo Hoo!").dig(:data, :product)
rescue ShopifyAPI::GraphQL::Request::UserError => e
p e
end
More Info
For more information checkout the API docs
Testing
cp env.template .env and fill-in .env with the missing values. This requires a Shopify store.
See Also
- Shopify Dev Tools - Command-line program to assist with the development and/or maintenance of Shopify apps and stores
- Shopify ID Export - Dump Shopify product and variant IDs —along with other identifiers— to a CSV or JSON file
ShopifyAPI::GraphQL::Tiny- Lightweight, no-nonsense, Shopify GraphQL Admin API client with built-in pagination and retryTinyGID- Build Global ID (gid://) URI strings from scalar values
License
The gem is available as open source under the terms of the MIT License.
Made by ScreenStaring