Headless Drupal 8#HeadlessDrupal
DrupalCamp Göteborg 2014
Ruben Teijeiro @rteijeiro
Drupal 7 Front-end Sucks!
DIVITIS
BUT
Drupal 8 Front-end is MortenDK Certified
I love Twig!! WTF!!WTF!!
BUT
"The front-end moves faster than Drupal, whether
Drupal likes it or not"
@eatings at DrupalCon Amsterdam
https://amsterdam2014.drupal.org/session/state-front-end
"The front-end moves faster than Drupal, whether Drupal likes it or not"
We have a solution
DECOUPLING
Decoupling Drupal Front-end makes easier to get
unexperienced front-end developers involved in Drupal
projects
Headless Drupal 8
We don't need contrib anymoar!!
Headless Drupal 8 REST modules are in Core
Don't forget the permissions
A little bit of CRUD
CRUD
CreateReadUpdateDelete
curl --include --request POST--user user:password--header 'Content-type: application/hal+json'http://localhost/drupal8/entity/node--data-binary '{"_links":{"type":{"href":"http://localhost/drupal8/rest/type/node/page"}}, "title":[{"value":"Node created using curl"}], "body": [{"value":"This is the body of the node created using curl"}]}'
Sample Create Request
HTTP/1.1 201 CreatedDate: Fri, 24 Oct 2014 10:26:50 GMTServer: Apache/2.2.22 (Debian)X-Powered-By: PHP/5.4.33-1~dotdeb.1Location: http://localhost/drupal8/entity/node/2
Sample Create Response
CRUD
CreateReadUpdateDelete
Sample Read Request
curl-H "Accept:application/hal+json" --request GET http://localhost/drupal8/node/2
Sample Read Response{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/node\/2"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/node\/page"},"http:\/\/localhost\/drupal8\/rest\/relation\/node\/page\/uid":[{"href":"http:\/\/localhost\/drupal8\/user\/1","lang":"en"}],"http:\/\/localhost\/drupal8\/rest\/relation\/node\/page\/revision_uid":[{"href":"http:\/\/localhost\/drupal8\/user\/1"}]},"uuid":[{"value":"f89b04b9-b2b2-4230-8e5c-92fb3856213d"}],"type":[{"target_id":"page"}],"langcode":[{"value":"en"}],"title":[{"value":"Node updated using curl","lang":"en"}],"_embedded":{"http:\/\/localhost\/drupal8\/rest\/relation\/node\/page\/uid":[{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/user\/1"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/user\/user"}},"uuid":[{"value":"b3e6e828-03fa-4a19-a706-6bba6f47edc4"}],"lang":"en"}],"http:\/\/localhost\/drupal8\/rest\/relation\/node\/page\/revision_uid":[{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/user\/1"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/user\/user"}},"uuid":[{"value":"b3e6e828-03fa-4a19-a706-6bba6f47edc4"}]}]},"status":[{"value":"1","lang":"en"}],"created":[{"value":"1414146410","lang":"en"}],"changed":[{"value":"1414147433","lang":"en"}],"promote":[{"value":"0","lang":"en"}],"sticky":[{"value":"0","lang":"en"}],"revision_timestamp":[{"value":"1414146410"}],"body":[{"value":"This is the body of the node updated using curl","format":null,"summary":null,"lang":"en"}]}
CRUD
CreateReadUpdateDelete
Sample Update Request
curl --include --request PATCH--user user:password--header 'Content-type: application/hal+json' http://localhost/drupal8/node/2--data-binary '{"_links":{"type":{"href":"http://localhost/drupal8/rest/type/node/page"}}, "title":[{"value":"Node updated using curl"}], "body": [{"value":"This is the body of the node updated using curl"}]}'
Sample Update Response
HTTP/1.1 204 No ContentDate: Fri, 24 Oct 2014 10:43:53 GMTServer: Apache/2.2.22 (Debian)X-Powered-By: PHP/5.4.33-1~dotdeb.1
CRUD
CreateReadUpdateDelete
Sample Delete Request
curl --include --request DELETE--user user:password--header 'Content-type: application/hal+json' http://localhost/drupal8/node/2
Sample Delete Response
HTTP/1.1 204 No ContentDate: Fri, 24 Oct 2014 10:51:04 GMTServer: Apache/2.2.22 (Debian)X-Powered-By: PHP/5.4.33-1~dotdeb.1
Views are in Core too!!
Thanks @pfrenssen forhttps://www.drupal.org/node/2317085
REST export
REST export settings
curl-H "Accept:application/hal+json" --request GET http://localhost/drupal8/node/rest
Sample Request
Sample Response[{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/node\/1"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/node\/article"},"http:\/\/localhost\/drupal8\/rest\/relation\/node\/article\/uid":[{"href":"http:\/\/localhost\/drupal8\/user\/1","lang":"en"}],"http:\/\/localhost\/drupal8\/rest\/relation\/node\/article\/revision_uid":[{"href":"http:\/\/localhost\/drupal8\/user\/1"}]},"uuid":[{"value":"5fad49bf-5c70-475d-9333-51c25caf62d5"}],"type":[{"target_id":"article"}],"langcode":[{"value":"en"}],"title":[{"value":"You don't get sick, I do","lang":"en"}],"_embedded":{"http:\/\/localhost\/drupal8\/rest\/relation\/node\/article\/uid":[{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/user\/1"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/user\/user"}},"uuid":[{"value":"b3e6e828-03fa-4a19-a706-6bba6f47edc4"}],"lang":"en"}],"http:\/\/localhost\/drupal8\/rest\/relation\/node\/article\/revision_uid":[{"_links":{"self":{"href":"http:\/\/localhost\/drupal8\/user\/1"},"type":{"href":"http:\/\/localhost\/drupal8\/rest\/type\/user\/user"}},"uuid":[{"value":"b3e6e828-03fa-4a19-a706-6bba6f47edc4"}]}]},"status":[{"value":"1","lang":"en"}],"created":[{"value":"1413657929","lang":"en"}],"changed":[{"value":"1413657957","lang":"en"}],"promote":[{"value":"1","lang":"en"}],"sticky":[{"value":"0","lang":"en"}],"revision_timestamp":[{"value":"1413657929"}],"revision_log":[{"value":"","lang":"en"}],"body":[{"value":"<p>Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.<\/p>\r\n","format":"basic_html","summary":"","lang":"en"}],"comment":[{"status":"2","cid":"0","last_comment_timestamp":"1413657957","last_comment_name":null,"last_comment_uid":"1","comment_count":"0","lang":"en"}]}]
vs
HAL JSON
Use HAL if you care about API definition
{ "_links": {
"self": { "href": "/your-api-links" }
},
"_embedded": {
"items": [
Array of serialized items
]
}
}
Use JSON if you only care about the content
[
{ "title": “This is your content title”,
"body": “This is your content body.”
}
]
How to enable JSON requests
Like a Ninja
Like a Ninja
core/modules/rest/config/install/rest.settings.yml
resources: entity:node: GET: supported_formats: - hal_json supported_auth: - basic_auth POST: supported_formats: - hal_json supported_auth: - basic_auth PATCH: supported_formats: - hal_json supported_auth: - basic_auth DELETE: supported_formats: - hal_json supported_auth: - basic_auth
Configuration Management – Single Import
Like a Boss
https://www.drupal.org/project/restui
Sample JSON Request
curl -H "Accept: application/json" --request GET http://localhost/drupal8/node/rest
Sample JSON Response
[{"nid":[{"value":"1"}],"uuid":[{"value":"5fad49bf-5c70-475d-9333-51c25caf62d5"}],"vid":[{"value":"1"}],"type":[{"target_id":"article"}],"langcode":[{"value":"en"}],"title":[{"value":"You don't get sick, I do"}],"uid":[{"target_id":"1"}],"status":[{"value":"1"}],"created":[{"value":"1413657929"}],"changed":[{"value":"1413657957"}],"promote":[{"value":"1"}],"sticky":[{"value":"0"}],"revision_timestamp":[{"value":"1413657929"}],"revision_uid":[{"target_id":"1"}],"revision_log":[{"value":""}],"path":[{"alias":null,"pid":null}],"body":[{"value":"<p>Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.<\/p>\r\n","format":"basic_html","summary":""}],"comment":[{"status":"2","cid":"0","last_comment_timestamp":"1413657957","last_comment_name":null,"last_comment_uid":"1","comment_count":"0"}],"field_image":[{"target_id":null,"display":null,"description":null,"alt":null,"title":null,"width":null,"height":null}],"field_tags":[{"target_id":null}]}]
BEWARE!!hal_json is the only format supported
for POST and PATCH methods
https://www.drupal.org/node/1964034
It needs work:
Getting a cleaner JSON response
Use Fields in View
Fields Raw Format
Clean JSON Response
[ { "title":"You don't get sick, I do", "body":"<p>Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends.<\/p>" }]
Happy now?
DEMO
Want to contribute?
How to POST a comment and other relational entities
Add special handling for collections in REST
Support ConfigEntity via REST
[meta] REST et al
File needs CRUD permissions to make REST work on entity/file/{id}
Serialize file content (base64) to support REST GET/POST/PATCH on file entity
Join the Code Sprints!!
Questions??
Thanks!
Top Related