Lightweight, no-nonsense, Shopify GraphQL Admin API client with built-in pagination and retry.
require "shopify_api/graphql/tiny"
gql = ShopifyAPI::GraphQL::Tiny.new("my-shop", token)
# Automatically retried
result = gql.execute(<<-GQL, :id => "gid:https://shopify/Customer/1283599123")
query findCustomer($id: ID!) {
customer(id: $id) {
id
tags
metafields(first: 10 namespace: "foo") {
edges {
node {
id
key
value
}
}
}
}
}
GQL
customer = result["data"]["customer"]
p customer["tags"]
p customer.dig("metafields", "edges", 0, "node")["value"]
updates = { :id => customer["id"], :tags => customer["tags"] + %w[foo bar] }
# Automatically retried as well
result = gql.execute(<<-GQL, :input => updates)
mutation customerUpdate($input: CustomerInput!) {
customerUpdate(input: $input) {
customer {
id
}
userErrors {
field
message
}
}
}
GQL
p result.dig("data", "customerUpdate", "userErrors")
In addition to built-in request retry ShopifyAPI::GraphQL::Tiny
also builds in support for pagination.
Using pagination requires you to include the Shopify PageInfo
object
in your queries and wrap them in a function that accepts a page/cursor argument.
The pager's #execute
is like the non-paginated #execute
method and accepts additional, non-pagination query arguments:
pager.execute(query, :foo => 123)
And it accepts a block which will be passed each page returned by the query:
pager.execute(query, :foo => 123) do |page|
# do something with each page
end
To use after
pagination, i.e., to paginate forward, your query must:
- Make the page/cursor argument optional
- Include
PageInfo
'shasNextPage
andendCursor
fields
For example:
FIND_ORDERS = <<-GQL
query findOrders($after: String) {
orders(first: 10 after: $after) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
id
email
}
}
}
}
GQL
pager = gql.paginate # This is the same as gql.paginate(:after)
pager.execute(FIND_ORDERS) do |page|
orders = page.dig("data", "orders", "edges")
orders.each do |order|
# ...
end
end
By default it is assumed your GraphQL query uses a variable named $after
. You can specify a different name using the :variable
option:
pager = gql.paginate(:after, :variable => "yourVariable")
To use before
pagination, i.e. to paginate backward, your query must:
- Make the page/cursor argument required
- Include the
PageInfo
'shasPreviousPage
andstartCursor
fields - Specify the
:before
argument to#paginate
For example:
FIND_ORDERS = <<-GQL
query findOrders($before: String) {
orders(last: 10 before: $before) {
pageInfo {
hasPreviousPage
startCursor
}
edges {
node {
id
email
}
}
}
}
GQL
pager = gql.paginate(:before)
pager.execute(FIND_ORDERS) do |page|
# ...
end
By default it is assumed your GraphQL query uses a variable named $before
. You can specify a different name using the :variable
option:
pager = gql.paginate(:before, :variable => "yourVariable")
By default ShopifyAPI::GraphQL::Tiny
will use the first pageInfo
block with a next or previous page it finds
in the GraphQL response. If necessary you can specify an explicit location for the pageInfo
block:
pager = gql.paginate(:after => %w[some path to it])
pager.execute(query) { |page| }
pager = gql.paginate(:after => ->(data) { data.dig("some", "path", "to", "it") })
pager.execute(query) { |page| }
The "data"
and "pageInfo"
keys are automatically added if not provided.
See the docs for more information.
cp env.template .env
and fill-in .env
with the missing values. This requires a Shopify store.
- 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
- ShopifyAPIRetry - Retry a ShopifyAPI request if rate-limited or other errors occur (REST and GraphQL APIs)
The gem is available as open source under the terms of the MIT License.
Made by ScreenStaring