Drupal 8的目标之一就是开箱即用,Drupal核心现在有了一套ReST API
这使得用户在使用Drupal 8的各种功能输入内容之后,不仅可以把内容呈现到标准的Drupal前端中,而且还可以输出给移动应用以及其他的能使用JSON数据的应用之中。
ReST
Drupal 8使用两个Module来提供ReST API。rest模块,为Angular JS之类的能够使用’Accept: application/json’头提供最简单的响应。他的工作很简单,只是Drupal 8 Entity的序列化输出。
下面是一个JSON响应的例子
{
"nid": [{
"value": "1"
}],
"uuid": [{
"value": "c0de5b48-d165-4970-8e05-5fccc692845f"
}],
"type": [{
"target_id": "article"
}],
"langcode": [{
"value": "und"
}],
"title": [{
"value": "Rusticus Vulpes"
}],
"uid": [{
"target_id": "0"
}],
"status": [{
"value": "1"
}],
"body": [{
"value": "This is the body of this node",
"format": "plain_text",
"summary": "And this is the summary"
}],
"comment": [{
"status": "2",
"cid": "5",
"last_comment_timestamp": "1411546941",
"last_comment_name": "",
"last_comment_uid": "1",
"comment_count": "5"
}],
"field_image": [{
"target_id": "28",
"display": null,
"description": null,
"alt": "Facilisi gemino nisl probo veniam.",
"title": "",
"width": "399",
"height": "308"
}],
"field_tags": [{
"target_id": "4"
}]
}
HAL
启用了hal模块,可以配置使用这一模块处理”Accept: application/hal+json”头。HAL的响应在普通的JSON响应内容之外,还加入了_links
和_embedded
两个键,用于包含关联信息和请求实体。
下面是一个hal+json的响应
{
"_links": {
"self": {
"href": "http:\/\/d8.dev\/node\/1"
},
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/node\/article"
},
"http:\/\/d8.dev\/rest\/relation\/node\/article\/uid": [{
"href": "http:\/\/d8.dev\/user\/0",
"lang": "und"
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/revision_uid": [{
"href": "http:\/\/d8.dev\/user\/0"
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/field_image": [{
"href": "http:\/\/d8.dev\/sites\/default\/files\/field\/image\/generateImage_Af38aP.jpg",
"lang": "und"
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/field_tags": [{
"href": "http:\/\/d8.dev\/taxonomy\/term\/4",
"lang": "und"
}]
},
"uuid": [{
"value": "c0de5b48-d165-4970-8e05-5fccc692845f"
}],
"type": [{
"target_id": "article"
}],
"langcode": [{
"value": "und"
}],
"title": [{
"value": "Rusticus Vulpes",
"lang": "und"
}],
"_embedded": {
"http:\/\/d8.dev\/rest\/relation\/node\/article\/uid": [{
"_links": {
"self": {
"href": "http:\/\/d8.dev\/user\/0"
},
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/user\/user"
}
},
"uuid": [{
"value": "aa69dd40-a5ad-4346-8d07-7c01f3e9e726"
}],
"lang": "und"
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/revision_uid": [{
"_links": {
"self": {
"href": "http:\/\/d8.dev\/user\/0"
},
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/user\/user"
}
},
"uuid": [{
"value": "aa69dd40-a5ad-4346-8d07-7c01f3e9e726"
}]
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/field_image": [{
"_links": {
"self": {
"href": "http:\/\/d8.dev\/sites\/default\/files\/field\/image\/generateImage_Af38aP.jpg"
},
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/file\/file"
}
},
"uuid": [{
"value": "84c9914b-d5e1-4235-b911-17e0381948bd"
}],
"uri": [{
"value": "http:\/\/d8.dev\/sites\/default\/files\/field\/image\/generateImage_Af38aP.jpg"
}],
"lang": "und"
}],
"http:\/\/d8.dev\/rest\/relation\/node\/article\/field_tags": [{
"_links": {
"self": {
"href": "http:\/\/d8.dev\/taxonomy\/term\/4"
},
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/taxonomy_term\/tags"
}
},
"uuid": [{
"value": "069bc39f-a41a-4fc6-a404-4df9e92e7b0b"
}],
"lang": "und"
}]
},
"status": [{
"value": "1",
"lang": "und"
}],
"body": [{
"value": "This is the body of this node",
"format": "plain_text",
"summary": "And this is the summary",
"lang": "und"
}],
"comment": [{
"status": "2",
"cid": "5",
"last_comment_timestamp": "1411546941",
"last_comment_name": "",
"last_comment_uid": "1",
"comment_count": "5",
"lang": "und"
}]
}
HAL响应和JSON相应的不同之处在于,HAL把JSON中用ID表达的相关数据例如图片、用户以及TAG等,替换成为_link
元素,其中包含类型、URI以及文档链接。
如何实践?
大多数DEMO需要这一ISSUE中的补丁。
要实践这些功能的最简单方法是使用drupal-rest-test工具来配置一个Drupal 8的ReST开发环境。该工具利用Drush安装一个Drupal,启用相关模块并进行配置和授权。这个项目的文档中包含了相关环境的信息。
补充说明
从HAL或者JSON中获取数据很简单,其响应内容具有基本的自我描述能力。真正的问题在于通过API对Node进行添加或者修改。多数此类文档都是来源于针对代码的反向工程。有个补丁可以使用application/json格式向Drupal提交新的Node。这是drupal-rest-test项目中post-rest.php
的实现;同一项目中,post-hal.php
中实现了application/hal+json格式的同样过程。
使用application/json提交node的例子
POST /entity/node
Content-type: application/json
{
"title": [
"test"
],
"type": [
{
"value": "article"
}
]
}
利用application/hal+json提交node的例子:
POST /entity/node Content-type: application/hal+json
{
"title": [
"test"
],
"type": [
{
"value": "article"
}
],
"_links": {
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/node\/article"
}
}
}
创建带有关系的Entity
创建同其他Entity具有关系的Entity很重要。例如留言Entity和Node Enity的关系。
使用application/json创建comment的例子(感谢@bertramakers)。
POST /entity/comment
Content-type: application/json
{
"entity_type": "node",
"field_name": "comment",
"entity_id": [
{
"target_id": 1
}
],
"comment_body": [
{
"value": "Example comment message."
}
]
}
使用application/hal+json完成同样内容
POST /entity/comment
Content-type: application/hal+json
{
"entity_type": [
"node"
],
"field_name": [
"comment"
],
"comment_body": [
"test"
],
"_links": {
"http:\/\/d8.dev\/rest\/relation\/comment\/comment\/entity_id": [
{
"href": "http:\/\/d8.dev\/node\/1"
}
],
"type": {
"href": "http:\/\/d8.dev\/rest\/type\/comment\/comment"
}
},
"_embedded": {
"http:\/\/d8.dev\/rest\/relation\/comment\/comment\/entity_id": [
{
"uuid": "af3710e7-fec3-4064-b500-b30d838236f5"
}
]
}
}
这就是使用HAL创建comment的最少数据。
使用Drupal和ReST搭建前端
我们创建了drupal-8-rest-angular项目来从可用度角度来对这一API进行测试。这个项目尝试使用AngularJS应用的方式来重新实现Bartik主题。这个项目使用Drupal 8中的自定义Views来从API以application/json格式获取需要的信息。
这个项目演示了包含API endpoint中缺失的创建完整Drupal前端的各种功能。目前尚无方法可以获取站点名称等Drupal基础站点信息。可以获取Block的信息,而获取一个Article的内容并展现给用户,平均需要5次json请求。
如果想要使用ReST,请关注meta issue并报告问题。