73

Click here to load reader

Headless Drupal 8

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

Page 1: Headless Drupal 8

Headless Drupal 8#HeadlessDrupal

DrupalCamp Göteborg 2014

Page 2: Headless Drupal 8

Ruben Teijeiro @rteijeiro

Page 3: Headless Drupal 8
Page 4: Headless Drupal 8
Page 5: Headless Drupal 8
Page 6: Headless Drupal 8
Page 8: Headless Drupal 8

Drupal 7 Front-end Sucks!

Page 9: Headless Drupal 8

DIVITIS

Page 10: Headless Drupal 8
Page 11: Headless Drupal 8

BUT

Page 12: Headless Drupal 8

Drupal 8 Front-end is MortenDK Certified

Page 13: Headless Drupal 8

I love Twig!! WTF!!WTF!!

Page 14: Headless Drupal 8

BUT

Page 15: Headless Drupal 8

"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

Page 16: Headless Drupal 8

"The front-end moves faster than Drupal, whether Drupal likes it or not"

Page 17: Headless Drupal 8

We have a solution

Page 18: Headless Drupal 8

DECOUPLING

Page 19: Headless Drupal 8

Decoupling Drupal Front-end makes easier to get

unexperienced front-end developers involved in Drupal

projects

Page 20: Headless Drupal 8
Page 21: Headless Drupal 8

Headless Drupal 8

Page 22: Headless Drupal 8

We don't need contrib anymoar!!

Page 23: Headless Drupal 8

Headless Drupal 8 REST modules are in Core

Page 24: Headless Drupal 8

Don't forget the permissions

Page 25: Headless Drupal 8
Page 26: Headless Drupal 8

A little bit of CRUD

Page 27: Headless Drupal 8
Page 28: Headless Drupal 8

CRUD

CreateReadUpdateDelete

Page 29: Headless Drupal 8

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

Page 30: Headless Drupal 8

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

Page 31: Headless Drupal 8

CRUD

CreateReadUpdateDelete

Page 32: Headless Drupal 8

Sample Read Request

curl-H "Accept:application/hal+json" --request GET http://localhost/drupal8/node/2

Page 33: Headless Drupal 8

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"}]}

Page 34: Headless Drupal 8

CRUD

CreateReadUpdateDelete

Page 35: Headless Drupal 8

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"}]}'

Page 36: Headless Drupal 8

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

Page 37: Headless Drupal 8

CRUD

CreateReadUpdateDelete

Page 38: Headless Drupal 8

Sample Delete Request

curl --include --request DELETE--user user:password--header 'Content-type: application/hal+json' http://localhost/drupal8/node/2

Page 39: Headless Drupal 8

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

Page 40: Headless Drupal 8
Page 41: Headless Drupal 8

Views are in Core too!!

Page 42: Headless Drupal 8
Page 43: Headless Drupal 8

Thanks @pfrenssen forhttps://www.drupal.org/node/2317085

Page 44: Headless Drupal 8
Page 45: Headless Drupal 8

REST export

Page 46: Headless Drupal 8

REST export settings

Page 47: Headless Drupal 8

curl-H "Accept:application/hal+json" --request GET http://localhost/drupal8/node/rest

Sample Request

Page 48: Headless Drupal 8

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"}]}]

Page 49: Headless Drupal 8
Page 50: Headless Drupal 8

vs

HAL JSON

Page 51: Headless Drupal 8

Use HAL if you care about API definition

{ "_links": {

"self": { "href": "/your-api-links" }

},

"_embedded": {

"items": [

Array of serialized items

]

}

}

Page 52: Headless Drupal 8

Use JSON if you only care about the content

[

{ "title": “This is your content title”,

"body": “This is your content body.”

}

]

Page 53: Headless Drupal 8

How to enable JSON requests

Page 54: Headless Drupal 8

Like a Ninja

Page 55: Headless Drupal 8

Like a Ninja

Page 56: Headless Drupal 8

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

Page 57: Headless Drupal 8

Configuration Management – Single Import

Page 58: Headless Drupal 8

Like a Boss

Page 59: Headless Drupal 8

https://www.drupal.org/project/restui

Page 60: Headless Drupal 8

Sample JSON Request

curl -H "Accept: application/json" --request GET http://localhost/drupal8/node/rest

Page 61: Headless Drupal 8

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}]}]

Page 62: Headless Drupal 8

BEWARE!!hal_json is the only format supported

for POST and PATCH methods

https://www.drupal.org/node/1964034

It needs work:

Page 63: Headless Drupal 8
Page 64: Headless Drupal 8

Getting a cleaner JSON response

Page 65: Headless Drupal 8

Use Fields in View

Page 66: Headless Drupal 8

Fields Raw Format

Page 67: Headless Drupal 8

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>" }]

Page 68: Headless Drupal 8

Happy now?

Page 69: Headless Drupal 8

DEMO

Page 70: Headless Drupal 8

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

Page 71: Headless Drupal 8

Join the Code Sprints!!

Page 72: Headless Drupal 8

Questions??

Page 73: Headless Drupal 8

Thanks!