7 min read

GraphQL vs REST API

Directus 9 supports both GraphQL and REST API, which one should I use? This article will cover the usage of both so you can decide which one suits you.

Directus 9 supports both GraphQL and REST API but which one should I use? Both methods are using the same core so there is no difference in terms of performance. It comes down to personal preference and what your application supports.

This article will cover the usage of both so you can decide which one suits you. It's quite long so I've included quick links to jump to the area's of interest.

In the examples below I use a free application called Postman which is a very useful playground for APIs and also provide a CURL example which can be translated in to other languages quite easily.

Authentication

Every API is different when it comes to Authentication but between GraphQL and REST API, you authenticate the same way. In Directus, the API user will have a token defined in the User Management portal. This token is used in the Bearer Token authentication header.

In Postman, create a new Collection and open the Authorization tab and paste you token into the Token field at the bottom.

Authorization example in Postman

For you application or website, you need to add the token to the authorization header. I'm writing these commands below in raw curl which can be easily translated into your chosen language.

curl -H "Authorization: Bearer your-bearer-token"

Query the API with GraphQL

GraphQL just has the one endpoint for all queries.

https://directus.example.com/graphql

To specify what table and columns to query, you must POST some information to the address above. This is a unique format also called GraphQL

query {
    articles {
        id
        title
        author {
            first_name
        }
    }
}

In Postman, create a new Request and choose POST as the method. The URL is the GraphQL endpoint as mentioned above. Lastly, click on the Body tab and choose GraphQL from the choices. Paste the GraphQL query into the Query box as seen below:

GraphQL query example in Postman

Once you click Send, you will receive a JSON response.

{
    data: [
        {
            "id": 1,
            "title": "Hello, world!",
            "author": {
                "first_name": "Robert"
            }
        }
    ]
}

The query in CURL is a little different. You will need to collapse your GraphQL into one line, then wrap it in a JSON array:

{"query": "GraphQL query goes here"}

So the query will look like this:

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "query { articles { id title author { first_name }}}"}' https://directus.example.com/graphql

But how do I query a specific record?

To query a specific record, you'll need to change your GraphQL query to:

query {
    articles_by_id(id: 15) {
        id
        title
        author {
            first_name
        }
    }
}

The JSON response is slightly different, where the data value is no longer a list.

{
    data: {
        "id": 15,
        "title": "More Information about this",
        "author": {
            "first_name": "Sarah"
        }
    }
}

Using what we know about CURL from the previous query, we'll wrap the GraphQL query in JSON again:

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "query { articles_by_id(id: 15) { id title author { first_name }}}"}' https://directus.example.com/graphql

Query the API with REST API

Rather than POST a GraphQL query, the REST API relys on the URL to specify the query.

https://directus.example.com/items/articles

With no parameters, this will return all columns for the data. To match the query we did in GraphQL, we need to add a paramenter to the URL.

https://directus.example.com/items/articles?fields=id,title,author.first_name

In Postman, create a new Request and choose GET as the method. The URL is the endpoint mentioned above with the fields parameter. You will notice the Query Params table will automatically populate with the parameters from the URL.

REST API example in Postman

Once you click Send, you will receive the same JSON response as the GraphQL query.

{
    data: [
        {
            "id": 1,
            "title": "Hello, world!",
            "author": {
                "first_name": "Robert"
            }
        }
    ]
}

The query in CURL is quite simple:

curl -H "Authorization: Bearer your-bearer-token" https://directus.example.com/items/articles?fields=id,title,author.first_name

But how do I query a specific record?

To query a specific record, we can reuse the URL from our previous query then add the ID after articles. I've added /15 before any parameters.

https://directus.example.com/items/articles/15?fields=id,title,author.first_name

The JSON response is again slightly different, where the data value is no longer a list but is the same as the GraphQL response for a single item.

{
    data: {
        "id": 15,
        "title": "More Information about this",
        "author": {
            "first_name": "Sarah"
        }
    }
}

Again, the CURL is quite simple:

curl -H "Authorization: Bearer your-bearer-token" https://directus.example.com/items/articles/15?fields=id,title,author.first_name

Creating a New Record in GraphQL

This is where GraphQL really shines. We know how to make a query, now we'll use the same approach to create a new record in the articles table.

To create a new record, you must POST the following query:

mutation {
    create_articles_item(data: { title: "Hello world!", body: "This is our first article" }) {
        id
        title
    }
}

Notice the query has changed to "mutation" and the content is supplied as JSON inside the brackets. Lastly, the scope { id title } is requesting those fields be returned in the response. Here is an example of the response:

{
    data: {
        "id": 16,
        "title": "Hello world!"
    }
}

Remember the GraphQL must be wrapped in JSON. So the CURL command looks like this.

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "mutation { create_articles_item(data: {title:"Hello world!", body:"This is our first article"}) { id title }}"}' https://directus.example.com/graphql

Creating a New Record in REST API

REST API is quite different in this area despite using the same method POST. Make sure the URL has the collection without a trailing slash.

https://directus.example.com/items/articles

In Postman, form data can be posted using either form-data or x-www-form-urlencoded options in the Body tab.

REST API POST example in Postman

The response contains the full scope of the record.

{
    data: {
        "id": 16,
        "status": "published",
        "date_created": "2022-02-05T13:00:00.000Z",
        "date_modified": null,
        "user_created": "bb6b83ed-aad3-4d6f-be43-1361cd9162cc",
        "user_modified": null,
        "title": "Hello world!",
        "body": "This is my first article",
        "author": 1
    }
}

In CURL, this request looks like this:

curl -H "Authorization: Bearer your-bearer-token" -X POST -F 'title=Hello world!' -F 'body=This is our first article' https://directus.example.com/items/articles

Or if you would prefer x-www-form-urlencoded:

curl -H "Authorization: Bearer your-bearer-token" -X POST -d 'title=Hello world!' -d 'body=This is our first article' https://directus.example.com/items/articles

Update a Record in GraphQL

This is very similar to the creation method. To update a record, you must POST the following query:

mutation {
    update_articles_item(id: 16, data: { title: "Updated Title!" }) {
        id
        title
    }
}

And the response includes the requested id and title:

{
    data: {
        "id": 16,
        "title": "Updated Title!"
    }
}

Remember the GraphQL must be wrapped in JSON. So the CURL command looks like this.

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "mutation { update_articles_item(id: 16, data: {title:"Updated Title!"}) { id title }}"}' https://directus.example.com/graphql

Update a Record in REST API

REST API update has a few differences to the creation request. The method needs to be changed to PATCH and the ID needs to be added to the URL:

https://directus.example.com/items/articles/16

The biggest change is the JSON input requirement rather than form-data. In Postman, choose the PATCH method and fill in the required fields.

REST API PATCH example in Postman

Observation: Boolean fields cause an error. Make sure to convert true and false to a string.

The CURL request is different as well.

curl -H "Authorization: Bearer your-bearer-token" -H "Content-type: application/json" -X PATCH -d '{"title": "Hello world!"}' https://directus.example.com/items/articles/16

Delete a Record in GraphQL

Again, this is very similar to the creation and update method. To delete a record, you must POST the following query:

mutation {
    delete_articles_item(id: 16) {
        id
    }
}

The response will be empty if successful. You'll know if something goes wrong when you get a JSON response.

Remember the GraphQL must be wrapped in JSON. So the CURL command looks like this.

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "mutation { delete_articles_item(id: 16) { id }}"}' https://directus.example.com/graphql

Delete a Record in REST API

REST API delete quite simple. The method needs to be changed to DELETE and the ID needs to be in the URL:

https://directus.example.com/items/articles/16

The CURL looks like this:

curl -H "Authorization: Bearer your-bearer-token" -X DELETE https://directus.example.com/items/articles/16

Advanced GraphQL Usage

Directus combined with GraphQL is very powerful. There are other parameters that can be added to a query to change what data is returned. Below I have combined a few examples such as filters, sort, limit and page.

query {
    articles(
        filter: { author: first_name: { _eq: "Robert" } } },
        sort: ["sort", "-date_created"],
        limit: 100,
        page: 2
    ) {
        id
        title
        author {
            first_name
        }
    }
}

What we expect to see is 101 - 200 of articles authored by Robert in descending order of when they where created.

I recommend reading through the Directus documentation for all the possiblities of the filters, such as _eq, _neq, _in, _nin, _between ...

The GraphQL must be wrapped in JSON so the CURL command looks something like this.

curl -H "Authorization: Bearer your-bearer-token" -X POST -d '{"query": "query { articles(filter: { author: first_name: { _eq: "Robert" } } }, sort: ["sort", "-date_created"], limit: 100, page: 2) { id title author { first_name }}}"}' https://directus.example.com/graphql

Advanced REST API Usage

Adding extra parameters works quite differently for REST APIs, the main difference is the filter paramenter which uses square brackets [ ] for each dimension of the filter array.

To replicate the same example as above, here is the request URL. Note the format of the filter parameter.

https://directus.example.com/items/articles?fields=id,title,author.first_name&filter[author][first_name][_eq]=Robert&sort=-date_created&limit=100&page=2

Observation: If you have any spaces in your filter values, make sure they are replaced by a +, also known as url encoded.

Again, what we expect to see is 101 - 200 of articles authored by Robert in descending order of when they where created.

The query in CURL is quite simple since all the parameters are in the URL.

curl -H "Authorization: Bearer your-bearer-token" https://directus.example.com/items/articles?fields=id,title,author.first_name&filter[author][first_name][_eq]=Robert&sort=-date_created&limit=100&page=2

Conclusion

Now you've seen examples from both GraphQL and REST API for queries, create, update, delete and advanced queries. Hopefully this has given you enough information to decide which method you prefer.

By continuing to use our website, you consent to use essential cookies. We also use optional tracking cookies which help us gather statistics to improve our services. Do you consent to these cookies?

I Consent Do not track