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
- Resources
- GET Request
- POST Request
- DELETE Request
- 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
<a href="https://example.com/node/<nid>?_format=hal_json">https://example.com/node/<nid>?_format=hal_json[/geshifilter-code]
Response
200 OK
{
"_links": {
"self": {
"href": "<a href="https://example.com/node/8?_format=hal_json"
">https://example.com/node/8?_format=hal_json"
</a> },
"type": {
"href": "<a href="https://example.com/rest/type/node/article"
">https://example.com/rest/type/node/article"
</a> },
"<a href="https://example.com/rest/relation/node/article/uid":">https://example.com/rest/relation/node/article/uid":</a> [
{
"href": "<a href="https://example.com/user/3?_format=hal_json",
">https://example.com/user/3?_format=hal_json",
</a> "lang": "en"
}
],
"<a href="https://example.com/rest/relation/node/article/revision_uid":">https://example.com/rest/relation/node/article/revision_uid":</a> [
{
"href": "<a href="https://example.com/user/3?_format=hal_json"
">https://example.com/user/3?_format=hal_json"
</a> }
],
"<a href="https://example.com/rest/relation/node/article/field_tags":">https://example.com/rest/relation/node/article/field_tags":</a> [
{
"href": "<a href="https://example.com/taxonomy/term/2?_format=hal_json",
">https://example.com/taxonomy/term/2?_format=hal_json",
</a> "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": {
"<a href="https://example.com/rest/relation/node/article/uid":">https://example.com/rest/relation/node/article/uid":</a> [
{
"_links": {
"self": {
"href": "<a href="https://example.com/user/3?_format=hal_json"
">https://example.com/user/3?_format=hal_json"
</a> },
"type": {
"href": "<a href="https://example.com/rest/type/user/user"
">https://example.com/rest/type/user/user"
</a> }
},
"uuid": [
{
"value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
}
],
"lang": "en"
}
],
"<a href="https://example.com/rest/relation/node/article/revision_uid":">https://example.com/rest/relation/node/article/revision_uid":</a> [
{
"_links": {
"self": {
"href": "<a href="https://example.com/user/3?_format=hal_json"
">https://example.com/user/3?_format=hal_json"
</a> },
"type": {
"href": "<a href="https://example.com/rest/type/user/user"
">https://example.com/rest/type/user/user"
</a> }
},
"uuid": [
{
"value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
}
]
}
],
"<a href="https://example.com/rest/relation/node/article/field_tags":">https://example.com/rest/relation/node/article/field_tags":</a> [
{
"_links": {
"self": {
"href": "<a href="https://example.com/taxonomy/term/2?_format=hal_json"
">https://example.com/taxonomy/term/2?_format=hal_json"
</a> },
"type": {
"href": "<a href="https://example.com/rest/type/taxonomy_term/tags"
">https://example.com/rest/type/taxonomy_term/tags"
</a> }
},
"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 <a href="https://example.com/rest/session/token">https://example.com/rest/session/token[/geshifilter-code]
POST Request
Request
<a href="https://example.com/entity/node">https://example.com/entity/node[/geshifilter-code]
Headers
| Header Name |
Header Value |
|---|
X-CSRF-Token |
(token from rest/session/token) |
Authorization |
Basic (hashed username/password) |
Content-Type |
application/hal+json |
Body
{
"_links": {
"type": {
"href": "<a href="https://example.com/rest/type/node/article"
">https://example.com/rest/type/node/article"
</a> }
},
"title": {
"value": "Test Article 2"
},
"type": {
"target_id": "article"
}
}
Response
200 OK
DELETE Request
Request
<a href="https://example.com/node/<nid>">https://example.com/node/<nid>[/geshifilter-code]
Headers
| Header Name |
Header Value |
|---|
X-CSRF-Token |
(token from rest/session/token) |
Authorization |
Basic (hashed username/password) |
Response
204 No Content
PATCH Request
Use the PATCH method to update an existing entity.
Request
<a href="https://example.com/node/<nid>">https://example.com/node/<nid>[/geshifilter-code]
Headers
| Header Name |
Header Value |
|---|
X-CSRF-Token |
(token from rest/session/token) |
Authorization |
Basic (hashed username/password) |
Content-Type |
application/hal+json |
Body
{
"_links": {
"type": {
"href": "<a href="https://example.com/rest/type/node/article"
">https://example.com/rest/type/node/article"
</a> }
},
"nid": {
"": {
"value": "8"
}
},
"type": {
"target_id": "article"
},
"promote": {
"value": "1"
},
"body": {
"": {
"value": "<p>foo bar baz</p>",
"lang": "en"
}
}
}
Response
204 No Content