Skip to main content

About GraphQL

Overview

Swan uses a GraphQL API, an API language that emerged in 2015 and quickly became an interesting alternative to REST or x-rpc. From GraphQL:

GraphQL is a query language for your API, and a server-side runtime for executing queries using a type system you define for your data. GraphQL isn't tied to any specific database or storage engine and is instead backed by your existing code and data.

Learning GraphQL

This page explains GraphQL concepts required to work with the Swan API. If you're new to GraphQL, consider reviewing the GraphQL documentation, or following this tutorial from How to GraphQL.

Advantages

  1. Strongly typed, permitting a robust API contract between Swan and API consumers. It's easy for clients to generate code to consume Swan's API, and easy to test a smooth integration (with contract testing, for example).
  2. Resilience. By giving power back to API clients, GraphQL has created a new class of APIs that are especially resilient to evolution.
  3. Finer command over the data you wish to fetch or over the way you wish to batch their requests thanks to GraphQL's request capacity. The freedom you have to consume Swan's API will also help you analyze client behavior and better respond to their needs.
  4. Introspection System, which allows you to ask Swan's server about which queries the API supports. A new developer can easily refer to it as built-in documentation. Learn more about introspection.
  5. Community. GraphQL creators helped create a powerful community from the start. Consider Apollo and The Guild.
  6. Future oriented. GraphQL is forward-thinking. In the Golden Age of APIs, when everything seems to come from APIs, GraphQL creates meta-graphs consolidating multiple different suppliers. With a stable and sustainable model, Swan believes GraphQL is the future of APIs.

Building blocks

Schema

The GraphQL Schema is the overarching structure that defines the entire API.

The schema includes root types—queries and mutations—which provide the entry point to get and modify information. The schema also describes the relationship between different types, and specifies what you can do with the API.

With schemas, you can validate the exact composition of your requests, and know in advance exactly what you'll get back. The schema is always up to date and is your main point of reference to integrate Swan.

Queries

Entry point to the API used to request information from the server. These are read-only operations, used only to fetch data from the remote API. Queries are similar to GET requests in a REST API.

Queries always begin with the keyword query, after which you'll choose the fields for which you want to fetch data.

Query example

Consider the following example, which queries user > mobilePhoneNumber. The payload returns the user's mobilePhoneNumber.

Note that this is a basic example. Consider this query example from onboarding to see more complexity, including nested fields. You can also explore all of Swan's queries in API Explorer.

Query
query { 
user(id: "$SWAN_USER_ID") { #query name
mobilePhoneNumber #field
}
}
Payload
{
"data": {
"user": {
"mobilePhoneNumber": "$USER_PHONE_NUMBER"
}
}
}
Query options

Swan often has two query options per object, such as user and users.

  • user requires an id and returns data about a single user.
  • users doesn't require an id and returns data about all of your users.

Mutations

There are entry points to a GraphQL API to make requests, which both take inputs.

Request typePurposeREST comparison
MutationsMake a changePUT or POST
QueriesFetch data from the remote APIGET

Each request starts with the keyword query or mutation, then specifies the field or fields you want to get back in the response.

Mutation example

Consider the following example, which calls the mutation updateAccount to update the account's language. Note the ... on UpdateAccountSuccessPayload, in which you can choose to return the account's language in the payload. Swan recommends adding validations systematically, as well as rejections.

Note that this is a basic example. Consider a requesting a merchant payment method to see more complexity. You can also explore all of Swan's mutations in API Explorer, including this one.

Mutation
mutation ChangeLanguage {
updateAccount( #mutation name
input: { accountId: "$YOUR_ACCOUNT_ID", language: en } #input information
) {
... on UpdateAccountSuccessPayload { #validation
__typename
account {
language #returns account language in payload
}
}
}
}

Payload
{
"data": {
"updateAccount": {
"__typename": "UpdateAccountSuccessPayload",
"account": {
"language": "en"
}
}
}
}

Types

Types are the building blocks of a GraphQL schema.

Each type represents a specific kind of data, such as objects, scalars, or enums.

  • Objects: Composite types that can contain fields, representing related data.
  • Scalars: Atomic types like Int, String, and Boolean, representing simple values.
  • Enums: Defines a set of possible values for a field.

Queries, mutations, and all of their inputs are strongly typed, making the schema not only possible but clean.

You can query every type in Swan's schema using GraphQL's built-in introspection.

Schema query
query {
__schema {
types {
name
description
}
}
}
Payload
{
"data": {
"__schema": {
"types": [
{
"name": "Account",
"description": "Whether you call it a wallet, monetary account, payment account or bank account, the notion of account is fundamental at Swan. All payment flows necessarily go through an account."
},
{
"name": "ID",
"description": "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID."
},
{
"name": "String",
"description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
},
{
"name": "Boolean",
"description": "The `Boolean` scalar type represents `true` or `false`."
},
{
"name": "Int",
"description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
},

{...} //response contains thousands of lines

]
}
}
}