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.
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
- 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).
- Resilience. By giving power back to API clients, GraphQL has created a new class of APIs that are especially resilient to evolution.
- 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.
- 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.
- Community. GraphQL creators helped create a powerful community from the start. Consider Apollo and The Guild.
- 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 {
user(id: "$SWAN_USER_ID") { #query name
mobilePhoneNumber #field
}
}
{
"data": {
"user": {
"mobilePhoneNumber": "$USER_PHONE_NUMBER"
}
}
}
Swan often has two query options per object, such as user
and users
.
user
requires anid
and returns data about a single user.users
doesn't require anid
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 type | Purpose | REST comparison |
---|---|---|
Mutations | Make a change | PUT or POST |
Queries | Fetch data from the remote API | GET |
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 the example of 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 ChangeLanguage {
updateAccount( #mutation name
input: { accountId: "$YOUR_ACCOUNT_ID", language: en } #input information
) {
... on UpdateAccountSuccessPayload { #validation
__typename
account {
language #returns account language in 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
, andBoolean
, 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.
query {
__schema {
types {
name
description
}
}
}
{
"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
]
}
}
}