
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
- Basic Auth Documentation from drupal.org
- "GET on content entities" from drupal.org
- Drupal 8 RESTful Web Services
- DELETE requests and Cookie Authentication in Drupal 8's REST
- POST, PATCH and DELETE request with Drupal 8 REST services
- Self-Documenting REST API Drupal contrib module
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