Square GraphQL Basics

Learn about the concepts, practices, and patterns you should be familiar with when working with Square GraphQL.

Link to section

Schema

A schema describes the objects and fields you can query for in the data model (graph), as well as the entry points, arguments, hierarchical relationships, and type information that determine valid query syntax. The following are some related concepts and terminology:

  • Fields - A property or attribute, such as phoneNumber or birthday. Each graph has one or more root fields that act as an entry point for graph data, such as merchants for the Merchants graph or inventoryChanges and inventoryCounts for the Inventory graph.
  • Objects - A collection of fields. The data type of a field can be a scalar, complex type, or enum, as a single value or an array. For example, the Customer.phoneNumber field is a String type and the Customer.address field is an Address type.
  • Enums - Defines the set of valid values for fields of the given enum type. For example, the Currency enum defines all possible values for the Money.currency field.
  • Interfaces - Defines fields that must be included in objects that implement the interface. For example, CatalogItem and CatalogCategory implement the CatalogObject interface, so both objects include all CatalogObject fields. The Catalog sample query in GraphQL Explorer shows how to use inline fragments to request fields based on different implementations.
  • Non-Null - An exclamation mark (!) appended to the data type of a field, which indicates that the value of the field must not be null when returned or when provided as an argument.

After signing in to GraphQL Explorer, you can browse the schema in the Documentation Explorer pane.

Link to section

Queries

A query operation retrieves specified data. Queries are enclosed in curly braces ({ }). Lines that begin with a # character are treated as comments and ignored. For example, a simple query might use the following format:

Every query contains at least one graph entry point and specifies the fields to return. In this example:

  • The entry point is merchants.
  • The requested fields are status and mainLocation for the seller and name, createdAt, and capabilities for the location.

Most graph entry points accept query arguments for filtering, sorting, or navigating through paged responses. For example, most entry points require that you filter by merchant ID and accept other filter parameters.

Note

For graphs that follow the GraphQL Cursor Connection Specification (such as Payments and Refunds), you specify a top-level edges list of node objects in your query instead of the top-level nodes. You can check the schema to find the valid syntax for each entry point.

Because mainLocation is a complex type, the query also specifies the Location subfields to retrieve. If successful, the example query returns results similar to the following:

This example query gets data from the Merchants graph and the implicitly supported Locations graph. A query can also include separate entry points for multiple graphs. For example, the following example gets information about the seller and a list of customers in the same query:

Link to section

Query responses

Responses can contain a data object, an extensions object, and an errors list. GraphQL responses don't return numeric response codes.

The data object in a response contains the query results.

{ "data": { # query results are here } }

If any errors are encountered while processing the query, Square returns an errors list.

{ "errors": [ { # error details are here } ] }

If the query partially succeeds, a response can contain both data with partial query results and errors.

{ "errors": [ { # error details are here } ], "data": { # query results are here } }

If you request the query's complexity score by including the x-graphql-include-debug header in the query, the response contains a top-level extensions field with debug information. Currently, only the requestId and complexityScore fields are returned.

{ "data": { # query results are here }, "extensions": { # debug fields are here } }
Link to section

Query components

The following sections describe features, syntax, and patterns you can use in your queries:

Note

Square also supports other GraphQL features, such as using aliases to rename fields in the response and the @skip and @include directives to conditionally return fields. For more information, see Introduction to GraphQL at Graphql.org.

You can specify the query operation type and an operation (or query) name. This syntax is required when sending multiple queries in a single request and recommended in general because naming your queries can help with reuse, debugging, and logging.

The following example query includes the query operation type and StatusAndCapabilities operation name:

You can filter a query to conditionally retrieve data based on specified criteria. All graph entry points (except currentMerchant) accept a filter query argument and expose a top-level input type that defines valid filtering criteria.

For example, the following cardsOnFile query uses the customerId, includeDisabled, and merchantId filter fields to a customer's cards on file that are enabled for payments:

These and other valid filters are defined in the CardOnFileFilter input type. If you want to filter by attributes that aren't included in the schema, you need to write your own application logic to iterate through and filter the results of one or more queries.

Note

Many Square GraphQL filters are equivalent to filters used for list and search endpoints in Square APIs.

Link to section

Required merchant ID filter

All graph entry points (except currentMerchant) require a merchant ID filter. You can query currentMerchant to get the merchant ID and other merchant-related fields, as shown in the following example:

{ currentMerchant { id status mainLocation { id } } }
Link to section

Retrieve a specific object

Most graph entry points allow you to specify an id filter that lets you retrieve a specific object. The following example query uses the id filter to retrieve a specific payment:

You can use variables to replace static or dynamic values in query arguments. For example, using a variable for the required merchant ID lets you reuse a query for different merchants.

The format for a variable is $variableName (a dollar sign followed by the variable name). To use a variable in a query, you must:

  1. Declare that the variable is used in the query.
  2. Replace the value in the query with the variable.
  3. Define the value of the variable.

The following example cURL query uses two variables: $merchantId and $searchText:

curl https://connect.squareupsandbox.com/public/graphql \ -X POST \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ -H 'Content-Type: application/json' \ -d '{ "query": "query CatalogTextSearch($merchantId: ID!, $searchText: [String!]!) { catalog(filter: { merchantId: { equalToAnyOf: [$merchantId]}, text: { value: $searchText}}) { nodes { id ... on CatalogItem { name }}}}", "variables": { "merchantId": "8QJT7EXAMPLE", "searchText": ["gluten", "free"]} }'

Note how the variables are used in the example:

  • Each variable and its type is declared as a query argument:

    query CatalogTextSearch($merchantId: ID!, $searchText: [String!]!)
  • The variables are used in the query:

    • $merchantId is used in the merchantId filter:

      merchantId: { equalToAnyOf: [$merchantId] }
    • $searchText is used in the text filter:

      text: { value: $searchText }
  • The values for both variables are defined in the variables object:

    "variables": { "merchantId": "8QJT7EXAMPLE", "searchText": ["gluten", "free"] }

Values are passed in a separate, transport-specific (usually JSON) variables dictionary, as shown in the previous example. You can also use a separate JSON file to pass in variable values. These variable names aren't prefixed with a $.

Link to section

Using variables in web-based explorers

In GraphQL Explorer and similar interfaces, variables are declared and used in the Query pane and their values are defined in the Query Variables pane.

The following example query uses the same $merchantId and $searchText variables:

query CatalogTextSearch($merchantId: ID!, $searchText: [String!]!) { catalog( filter: { merchantId: {equalToAnyOf: [$merchantId] } text: {value: $searchText} } ) { nodes { id ... on CatalogItem { name } } } }

Note

The sample queries in GraphQL Explorer also show how to use variables in queries and pass in their values.

Fragments are reusable snippets used to request the same set of predefined fields for an object. Fragments can help simplify and organize complex queries and make them easier to maintain. Fragments are defined outside of a query and referenced from the query using the ... fragmentName syntax.

The following example query defines a set of fields for a contactInfo fragment and then references the fragment from Customer objects in the query:

Inline fragments are embedded in the query and let you independently request fields for implementations of a polymorphic object. For example, the CatalogObject object in the Catalog graph can represent one of many catalog object implementations, such as:

  • CatalogCategory
  • CatalogImage
  • CatalogItem
  • CatalogItemVariation
  • CatalogModifier
  • CatalogTax

Each implementation inherits some fields from the base CatalogObject object and also exposes its own type-specific fields. The following example query uses the ... on typeName syntax to request type-specific fields for CatalogCategory, CatalogItem, and CatalogItemVariation subtypes.

For another example of using inline fragments to request fields based on different implementations, see the Catalog sample query in GraphQL Explorer.

Pagination is used to retrieve all the results of a query using paged responses. Square GraphQL uses the cursor method of pagination. You retrieve pages of data by optionally specifying the page size and then use a pointer (cursor) to keep track of where the next page of data should be retrieved from.

The following example query uses pagination to retrieve all orders for a given merchant and location:

  • The first field specifies the page size, which is the maximum number of items to return in each response page. If you omit this field, the default page size is used.
  • The pageInfo field requests hasNextPage and endCursor to use for forward pagination.

The following is an example paged response:

If more pages of data are available, hasNextPage is true and endCursor contains the cursor.

In your next query, include the after field and provide the cursor from the previous response, as shown in the following example:

Continue using the cursor from each response page in a subsequent query until you retrieve all response pages.

In the last response page, hasNextPage is false and endCursor is null, as shown in the following example:

The pagination process might vary depending on the Square graph being queried. For example, payments and refunds can also be paginated in a backward direction using the last and before fields with startCursor.

In addition, valid first and last page size values might vary depending on the graph or the complexity score of the query.

Link to section

See also