GraphQL Introduction
GraphQL is an API query language originally developed by Facebook.
We've elected to develop our API using GraphQL as much of the data in Shopfront is related to each other and it allows us to easily add new features without worrying about breaking existing applications.
If you've never used GraphQL before, we would highly suggest going through the official GraphQL learning resources. This will provide you with the most information and a full list of features that you can use with GraphQL, but we've compiled a quick basics here.
Prefer to explore the schema directly? Download the full GraphQL schema (SDL).
Getting Started
Before you get started with GraphQL, make sure you authenticate your application. More information can be found here.
GraphQL essentially works the same was that any REST or SOAP API does,
however instead of multiple having multiple URLs (like REST), you instead
have a single endpoint (/graphql) (similar to SOAP). Through this
endpoint you can query any object or perform a mutation.
If you are getting data from Shopfront, that request is called a query.
If you are sending data to / updating data in Shopfront, that request is called a mutation.
The best way to learn is typically to do, so let's make a request to our API, we'll retrieve a list of all the Users for our vendor (not sure how to read this? The MDN web docs has a good set of instructions):
POST /api/v2/graphql HTTP/1.1
Host: example.onshopfront.com
Authorization: Bearer 123abc
Content-Type: application/json
Accept: application/json
{
"query": "{\n users {\n id,\n name\n }\n}"
}
Let's go through this request. We'll start off at the top and work our way down:
POST /api/v2/graphql HTTP/1.1
Host: example.onshopfront.com
This is just making a standard POST request to the URL
https://example.onshopfront.com/api/v2/graphql. You should replace
example with your store URL.
You might have noticed we're using a POST request even through we are retrieving data (typically a GET request). This is because GraphQL requests can end up being quite long and sending it all through a URL can lead to issues. The Shopfront API supports making GraphQL requests using any request method, but we highly suggest using POST for all requests.
Authorization: Bearer 123abc
This is the authorisation bearer token header that you will have been provided after completing the authentication.
Content-Type: application/json
The Content-Type header specifies what type of content we're providing, in
this case it's JSON. We also support using the application/graphql
content type, however some client applications don't recognise it and it
gets handled slightly differently, so we recommend sticking with the standard
application/json.
Accept: application/json
This lets the server know what sort of data you would like returned, we
currently only support returning JSON so you're safe to leave it off if
you'd like.
{
"query": "{\n users {\n id,\n name\n }\n}"
}
This is where things start to get interesting, this is simply JSON with
a key called query which (surprise) contains the GraphQL query, let's
format it and have a look:
{
users {
id,
name
}
}
This is a really simple query that gets all the users and returns their id and name. After performing the query you'll receive a response that looks something like this:
{
"data": {
"users": [
{
"id": "123abc",
"name": "User #1"
},
{
"id": "321cba",
"name": "User #2"
}
]
}
}
That's all there really is to it. If there was an error during your
query you'll have an error key in the returned data (for example):
{
"data": {
"users": null
},
"errors": [{
"message": "Something bad happened"
}]
}
If you need to pass variables
to the server, you can add a variables key to the JSON that you
send to the server.
Now that you've got the basics under control, it's time to learn some more at the official GraphQL website or jump into developing your application with our API.
Interfaces & Unions
Some fields can return one of several different types of object - these are represented in our schema as GraphQL
Interfaces or Unions.
Because the exact type being returned isn't known ahead of time, you need to use an "inline fragment"
(... on TypeName) to request fields that only exist on one of the possible types.
As an example, the item field on a sale's line items (SaleItem) can be a
Product, GiftCard,
EnterpriseGiftCard or
Surcharge. To request fields specific to one of these types, wrap them in
an inline fragment for that type:
{
sale(id: "123abc") {
items {
id,
item {
id,
... on Product {
name
},
... on GiftCard {
code,
currentAmount
}
}
}
}
}
Fields declared directly on the Interface itself (like id above, which is declared by SellableInterface) can be
requested directly, without an inline fragment - a field only qualifies for this if it's declared on the
Interface, not merely because every concrete type happens to implement a field with the same name. Union types
don't declare any fields of their own, so every field on a Union must be requested through an inline fragment.
Fields specific to a single type must be wrapped in ... on TypeName { } - if the object returned isn't of that
type, those fields are simply omitted from the response.
You can include inline fragments for as many of the possible types as you like within the same query - only the fragment matching the actual returned type will be populated.
Field-Level Validation
Shopfront supports performing field-level validation on inputs before attempting to process the query / mutation. When
using a field that supports field-level validation, your input will be checked during the parsing stage of the request.
If your input fails validation, an error will be returned in the errors array with the message containing the issue.
Fields that support validation can be found throughout the documentation with each field documenting the rules it follows.
Currently this feature is opt-in only, to enable it, please set the
X-GraphQL-Validate-Variablesheader totrue. This will become the default in the future.