GraphQL vs REST API
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.
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:
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.
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.
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.
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.