Skip to content Skip to navigation

Drupal 8 REST Requests

In November, 2015, the Stanford Web Services team got to dive into Drupal 8 during a weeklong sprint. I was excited to look at the RESTful web services that Drupal 8 gives out-of-the-box; what follows is my documentation of the various types of requests supported, required headers, responses, and response codes.

This is not intended to be an exhaustive documentation of RESTful web services in Drupal 8. However, I have pulled information from various posts around the Web, and my own experimentation, into this post.

A REST client application (e.g., Paw for Mac OS X) is extremely handy for experimenting with RESTful web services in Drupal 8.

Contents

  1. Resources
  2. GET Request
  3. POST Request
  4. DELETE Request
  5. PATCH Request

Resources

GET Request

The GET request is the simplest, and requires no authentication (if permissions are configured to allow anonymous users to "Access GET on Content resource"). Just send a GET request to the node path and add a _format=hal_json URL parameter.

More documentation available at drupal.org.

Request

https://example.com/node/<nid>?_format=hal_json

Response

200 OK

{
  "_links": {
    "self": {
      "href": "https://example.com/node/8?_format=hal_json"
    },
    "type": {
      "href": "https://example.com/rest/type/node/article"
    },
    "https://example.com/rest/relation/node/article/uid": [
      {
        "href": "https://example.com/user/3?_format=hal_json",
        "lang": "en"
      }
    ],
    "https://example.com/rest/relation/node/article/revision_uid": [
      {
        "href": "https://example.com/user/3?_format=hal_json"
      }
    ],
    "https://example.com/rest/relation/node/article/field_tags": [
      {
        "href": "https://example.com/taxonomy/term/2?_format=hal_json",
        "lang": "en"
      }
    ]
  },
  "uuid": [
    {
      "value": "a57f21eb-a4fe-4c04-8507-7a9cb1255834"
    }
  ],
  "type": [
    {
      "target_id": "article"
    }
  ],
  "langcode": [
    {
      "value": "en",
      "lang": "en"
    }
  ],
  "title": [
    {
      "value": "Test Article 2",
      "lang": "en"
    }
  ],
  "_embedded": {
    "https://example.com/rest/relation/node/article/uid": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/user/3?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/user/user"
          }
        },
        "uuid": [
          {
            "value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
          }
        ],
        "lang": "en"
      }
    ],
    "https://example.com/rest/relation/node/article/revision_uid": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/user/3?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/user/user"
          }
        },
        "uuid": [
          {
            "value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
          }
        ]
      }
    ],
    "https://example.com/rest/relation/node/article/field_tags": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/taxonomy/term/2?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/taxonomy_term/tags"
          }
        },
        "uuid": [
          {
            "value": "14bd6eeb-f0f1-4fd1-b200-e27246318b7c"
          }
        ],
        "lang": "en"
      }
    ]
  },
  "status": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "created": [
    {
      "value": "1446588457",
      "lang": "en"
    }
  ],
  "changed": [
    {
      "value": "1446589578",
      "lang": "en"
    }
  ],
  "promote": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "sticky": [
    {
      "value": "0",
      "lang": "en"
    }
  ],
  "revision_timestamp": [
    {
      "value": "1446588457"
    }
  ],
  "revision_translation_affected": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "default_langcode": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "comment": [
    {
      "status": "2",
      "cid": "0",
      "last_comment_timestamp": "1446588457",
      "last_comment_name": null,
      "last_comment_uid": "3",
      "comment_count": "0",
      "lang": "en"
    }
  ]
}

Authentication

POST, DELETE and PATCH requests require a CSRF token, as well as HTTP Basic Authentication (with a user's Drupal user name and password).

Get the token at https://example.com/rest/session/token

POST Request

Request

https://example.com/entity/node

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)
Content-Typeapplication/hal+json

Body

{
  "_links": {
    "type": {
      "href": "https://example.com/rest/type/node/article"
    }
  },
  "title": {
    "value": "Test Article 2"
  },
  "type": {
    "target_id": "article"
  }
}

Response

200 OK

DELETE Request

Request

https://example.com/node/<nid>

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)

Response

204 No Content

PATCH Request

Use the PATCH method to update an existing entity.

Request

https://example.com/node/<nid>

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)
Content-Typeapplication/hal+json

Body

{
  "_links": {
    "type": {
      "href": "https://example.com/rest/type/node/article"
    }
  },
  "nid": {
    "": {
      "value": "8"
    }
  },
  "type": {
    "target_id": "article"
  },
  "promote": {
    "value": "1"
  },
  "body": {
    "": {
      "value": "<p>foo bar baz</p>",
      "lang": "en"
    }
  }
}

Response

204 No Content

Categories: 

Comments

Checkout drupal.org/project/rest_api_doc to have this auto built for your site

Ah, thanks for the reminder. We did lean heavily on the Self-Documenting REST API module (which is awesome).

I've updated the post to add that as a resource.

Just what's needed to help a developer get started with Drupal 8 REST.

Did you try posting a node with an Entity Reference field linking to another content type?

How is an Entity Reference field populated? A Postman example?
Thanks!

What is the format for an entity reference in POST for a node?

The bundle field is an example of setting the value for an entity reference field. In that case the entity id is a string but if it was numeric you can set the target_id to the relevant entity id

Hi,

How can i retrieve all nodes (by passing page and limit parameters).

Thanks
BBI fondative

I'm trying to POST a .pdf to be saved in my files directory. Any luck doing something like that?

Add new comment

By submitting this form, you accept the Mollom privacy policy.