storefront-go
is a Go client for Shopify's Storefront API. It's focused on the ergonomics around querying rather than on mutation, using schema introspection and code generation to provide types, but otherwise providing a pretty bog standard HTTP client interface.
Documentation is "best effort" given the existing documentation within the schema and doesn't conform to Go best standards with respect to formatting.
⚠️ IMPORTANT NOTE: This library is highly experimental and currently very minimally tested. It's being dogfooded in a current commercial project, but isn't production-worthy, and is probably heavily broken.
storefront-go
uses generics to streamline some aspects of working with the API, and therefore requires Go 1.18 (the current release candidate version [RC1] works, as well as beta 2). There is no plan to support Go < 1.18.
The current stable schema, 2022-01
, is provided in the schema/2022-01
directory. To use a different API version, use the Apollo CLI to introspect your store's Storefront API endpoint with your access token provided as the X-Shopify-Storefront-Access-Token
header. Code generation uses the JSON version:
npm install -g graphql apollo
# or yarn global graphql apollo
apollo schema:download schema/<API_VERSION>/schema.json \
--endpoint=https://<DOMAIN>/api/<API_VERSION>/graphql.json \
--header="X-Shopify-Storefront-Access-Token: <ACCESS_TOKEN>"
For reference, to grab the native GraphQL schema, use Rover instead:
npm install -g rover
# or yarn global rover
rover graph introspect https://<DOMAIN>/api/<API_VERSION>/graphql.json \
--header "X-Shopify-Storefront-Access-Token: <ACCESS_TOKEN>" \
> schema/<API_VERSION>/schema.graphqls```
Types from introspecting the current stable 2022-01
schema are already implemented in types.go
. If, as above, you need to target a different API version, manually run scripts/parse.go
, pointing to the schema file you'd like to use (using go generate
directly won't be a good option until 1.18 final). So, presently:
go1.18rc1 run scripts/parse.go <PATH_TO_SCHEMA>
This will overwrite the existing types.go
.
go1.18rc1 get github.com/boatilus/storefront-go
import (
"log"
"github.com/boatilus/storefront-go"
)
sf := storefront.NewClient("<DOMAIN>", "<ACCESS_TOKEN>")
var set storefront.Set
if err := sf.Query(`{
collections(first: 1) {
edges {
node {
title
}
}
}
}`, &set); err != nil {
// Handle
}
log.Print(set.Data.Collections.Edges[0].Node.Title)
// Outputs: Example Product Title
A convenience function, LoadQuery
, is also provided to make reading queries from the filesystem a bit easier. There is no syntax validation or otherwise -- it merely reads the file contents and returns a string you can then pass into Query
.
import "github.com/boatilus/storefront-go"
sf := storefront.NewClient("<DOMAIN>", "<ACCESS_TOKEN>")
q, err := storefront.LoadQuery("path/to/query.graphql")
if err != nil {
// Handle
}
var set storefront.Set
if err := sf.Query(q, &set); err != nil {
// Handle
}
This is a little complicated.
Currently, Shopify doesn't provide a container that'd let us spin up a local test store/Storefront endpoint, so to ensure types are being generated correctly, we really have to rely on end-to-end tests against real (or real demo) stores.
To set up the environment for passing tests, do the following:
Create a .env in the project root:
SHOPIFY_DOMAIN=<YOUR_STORE_DOMAIN>
SHOPIFY_STOREFRONT_ACCESS_TOKEN=<YOUR_ACCESS_TOKEN>
Create an expected.json
in the test
directory, providing values from your store. A test/expected.schema.json for expected.json
is included for reference. Minimally, expected.json
should contain something like:
{
"collections": {
"title": "Home page",
"description": "Basic description"
},
"shop": {
"name": "Shop name"
}
}
You can then run go test
using something like godotenv to inject .env
into the environment (or specify them in whatever way you prefer):
godotenv go test
# or, currently:
# godotenv go1.18rc1 test