Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

JSON:API

JSON:API is a core module that serves site content as JSON at ready-made addresses. It is needed when another program reads Drupal data: a mobile app, a React or Vue interface, a neighbouring site. No code is required — it is enough to enable the module.

Enabling

vendor/bin/drush en jsonapi

The module creates addresses for every entity type of the site by itself. No files in the blog module are needed for this.

The list of articles

The address of a collection follows the rule /jsonapi/entity_type/bundle:

curl -g "http://127.0.0.1:8888/jsonapi/node/article"

The same address can be opened in a browser. The response is JSON with the list of articles:

{
  "data": [
    {
      "type": "node--article",
      "id": "3f0c6a1e-8a53-4b0a-9c1d-2f6d0e7b4a11",
      "attributes": {
        "title": "First article",
        "status": true,
        "created": "2026-03-01T10:00:00+00:00"
      },
      "relationships": {
        "field_tags": { "data": [] }
      }
    }
  ],
  "links": {
    "self": { "href": "http://127.0.0.1:8888/jsonapi/node/article" }
  }
}

Ordinary fields are in attributes, references to other entities in relationships. The id here is not the node number but a UUID: a long unique identifier every entity has.

One article

curl -g "http://127.0.0.1:8888/jsonapi/node/article/3f0c6a1e-8a53-4b0a-9c1d-2f6d0e7b4a11"

The UUID from the list goes at the end of the address. The response holds a single object in data.

Query parameters

ParameterWhat it does
filter[status]=1Keeps the records with this field value
sort=-createdSorts; a minus means descending
page[limit]=5Limits the count
page[offset]=5Skips the first records
fields[node--article]=title,createdReturns only the listed fields
include=field_tagsAdds the referenced entities to the response

Parameters are joined with &:

curl -g "http://127.0.0.1:8888/jsonapi/node/article?sort=-created&page[limit]=5&fields[node--article]=title,created"

The request returns the five latest articles with only the title and the date. The -g switch tells curl not to interpret the square brackets in its own way.

Access

JSON:API respects the same permissions as the site. An anonymous visitor gets only published articles and only with the "View published content" permission. Unpublished nodes and restricted fields do not get into the response.

Writing

By default the module is read-only. Creating, updating and deleting are enabled at Configuration → Web services → JSON:API, the address /admin/config/services/jsonapi. After that POST, PATCH and DELETE requests work for users with the right permissions; the request must be authenticated — for example through the core HTTP Basic Authentication module.

Your own JSON address

If you need a response with your own structure rather than the whole node, an ordinary route and a controller returning JsonResponse will do — it is shown in the lesson about controllers. Choose JSON:API for standard operations on entities and your own controller for a special response.

Common mistake

A JSON:API address uses the UUID, not the node number: /jsonapi/node/article/5 returns 404. You can find the UUID in the collection response or in code — $node->uuid(). To get a node by its number, use a filter: /jsonapi/node/article?filter[drupal_internal__nid]=5.

Thanks for reading!

Donate to the site — we work hard for you.