API Old and New

The underlying technology of GraphCMS received a fantastic update and now the previous Relay and Simple API's have been merged into one. One end point, many possibilities!

To make this new "one-api-to-rule-them-all", a few changes were necessary to bring the APIs into parity.

Queries

by the API URL and your project ID:

https://api-$REGION.graphcms.com/v1/$YOUR_PROJECT_ID$/$STAGE

This URL can be used by clients like Apollo, Lokka or simple curl-request. For example if you wan't to query the title of all posts within your project you could use the following curl command:

curl 'https://api-$REGION.graphcms.com/v1/$YOUR_PROJECT_ID$/$STAGE' -H 'content-type: application/json' --data-binary '{"query":"query {allPosts {title}}"}' --compressed

No more explicit all- prefix

The API will be a little different from what you are used in the current version. The all-Prefix from the queries is gone now. So a simple Query might look like this:

old
new
query {
allPosts {
id
title
content
}
}
query {
posts {
id
title
content
}
}

Filtering

If you want to filter you now need to use the where argument:

old
new
query {
allAuthors(
filter: {
age_gt: 18
}) {
id
title
content
}
}
query {
authors(where: {
age_gt: 18
}) {
id
name
}
}

This will be familiar to may developers who've spent time writing SQL queries.

A more advanced example:

old
new
query {
posts(filter: {
title_in: ["My biggest Adventure", "My latest Hobbies"]
}) {
id
title
status
}
}
query {
posts(where: {
title_in: ["My biggest Adventure", "My latest Hobbies"]
}) {
id
title
status
}
}

and as before, you can chain boolean operators AND and OR:

old
new
query {
allPosts(filter: {
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
isPublished: true
}]
}) {
id
title
isPublished
}
}
query {
posts(where: {
AND: [{
title_in: ["My biggest Adventure", "My latest Hobbies"]
}, {
status: PUBLISHED
}]
}) {
id
title
status
}
}

Ordering

An example of ordering the response, the same as previous

query {
posts(orderBy: title_ASC) {
id
title
status
}
}

Pagination

An example of a paginating query.

query {
posts(
first: 2
skip: 1
) {
id
title
}
}
query {
posts(
first: 2
after: "cixnen24p33lo0143bexvr52n"
) {
id
title
}
}

Mutations

Mutations look different with the new syntax. The primary difference is the addition of a new data field in the body of the mutation. See below for examples.

Create

old
new
mutation {
createAuthor(
age: 42
email: "zeus@example.com"
name: "Zeus"
) {
id
name
}
}
mutation {
createAuthor(
data: {
age: 42
email: "zeus@example.com"
name: "Zeus"
}
) {
id
name
}
}

Update

Update takes both a data field AND a where field

old
new
mutation {
updateAuthor(
email: "zeus2@example.com"
name: "Zeus2"
) {
id
name
}
}
mutation {
updateAuthor(
data: {
email: "zeus2@example.com"
name: "Zeus2"
}
where: {
email: "zeus@example.com"
}
) {
id
name
}
}

Upsert (Update OR Insert)

When we want to either update an existing node, or create a new one in a single mutation, we can use upsert mutations. Previously this was accomplished with the little documented utility, updateOrCreate.

mutation {
upsertAuthor(
where: {
email: "zeus@example.com"
}
create: {
email: "zeus@example.com"
age: 42
name: "Zeus"
}
update: {
name: "Zeus"
}
) {
name
}
}

Since this is not a very DRY exmaple, a more common practice would be something like this:

mutation UpsertAuthor($email: String!, $age: Int, $name: String) {
upsertAuthor(
where: {
id: $email
}
create: {email: $email, age: $age, name: $name}
update: {email: $email, age: $age, name: $name}
) {
name
id
email
}
}

Note, email here is a unique field on the model. For more about variables, look here.‚Äč

Delete

Deleting builds on the usage of where but omits the data field.

old
new
mutation {
deleteAuthor(
id: "12345"
) {
id
name
}
}
mutation {
deleteAuthor(where: {
id: "cjcdi63l20adx0146vg20j1ck"
}) {
id
name
email
}
}