Click here to load reader
Upload
ruben-teijeiro
View
565
Download
1
Embed Size (px)
DESCRIPTION
"The front-end moves faster than Drupal, whether Drupal likes it or not" This reference from "The state of the Front-end" session at DrupalCon Amsterdam explains that we need different ways to retrieve content from a Drupal site for an easy integration with new front-end frameworks. This allows non-experienced front-end developers to start theming Drupal using the tools they are used to. In this session you will learn how to enable the new Drupal 8 features that exports all the content in a front-end friendly format (JSON, HAL). Also I'll show a simple Backbone.js application that will load that content and print it using only the specific markup you need.
Citation preview
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!