创建新资源(POST)
此页面展示了 JSON:API 模块 的各种 POST 请求示例。
POST 请求用于创建新资源。如果需要修改资源,请使用 PATCH。
JSON:API 规范(因此 JSON:API 模块)仅支持每个 POST 请求创建一个资源。对于 Drupal,这意味着无法(仅使用该模块)在一个请求中创建多个实体。如果你想在创建父实体的同时创建被引用的实体,就需要这种功能。虽然 JSON:API 不支持此行为,但像 Subrequests 这样的模块可以帮助实现。
启用创建操作
访问 /admin/config/services/jsonapi
并勾选 “接受所有 JSON:API 创建、读取、更新和删除操作” 选项。

认证
通常 POST 请求需要某种形式的认证。以下示例均使用基本认证(Basic Authentication),即使用具有创建相应内容权限的现有网站用户的用户名和密码。
启用 HTTP Basic Authentication (basic_auth
) 模块,为 API 用户(及角色)设置权限,并在请求头的 'Authorization' 中设置编码后的用户名和密码。
此页面上的示例请求头需要一个用户名为 'api'、密码为 'api' 的 Drupal 用户。
请求头
以下请求头在所有 POST 请求中都是必须的,以确保 JSON:API 请求和响应的正确性。
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
以下请求头在示例中需要使用:
Authorization: Basic YXBpOmFwaQ==
Curl
假设你的数据保存在 payload.json
文件中。
curl \
--user api:api \
--header 'Accept: application/vnd.api+json' \
--header 'Content-type: application/vnd.api+json' \
--request POST http://drupal.d8/jsonapi/node/article \
--data-binary @payload.json
基本 POST 请求
URL: http://example.com/jsonapi/node/article
请求体
{
"data": {
"type": "node--article",
"attributes": {
"title": "我的自定义标题",
"body": {
"value": "自定义内容",
"format": "plain_text"
}
}
}
}
响应
HTTP 201 (Created) 响应。响应体包含已创建实体的 JsonApi 响应。
带关系的 POST 请求
URL: http://example.com/jsonapi/node/article
实体引用字段必须作为 relationships
设置,而不是 attributes
。如果你未这样做,将会看到错误信息 “The following relationship fields were provided as attributes”,并附带有问题的字段列表。
id
键必须包含实体的UUID,而不是 ID;例如:faba301b-bdf5-4658-abc1-e173b815984f
。
请求体
{
"data": {
"type": "node--article",
"attributes": {
"title": "管理员创建的文章",
"body": {
"value": "自定义内容",
"format": "plain_text"
}
},
"relationships": {
"uid": {
"data": {
"type": "user--user",
"id": "{{用户1的UUID}}"
}
},
"field_taxonomy_term_reference": {
"data": {
"type": "taxonomy_term--{{bundle}}",
"id": "{{术语的UUID}}"
}
}
}
}
}
响应
HTTP 201 (Created) 响应。响应体包含已创建实体的 JsonApi 响应。
使用 REST API 的 POST 方法
首先创建一个带有 REST 资源的自定义模块,并通过 /admin/config/services/rest 启用。
<?php
namespace Drupal\rest_examples\Plugin\rest\resource;
use Drupal\node\Entity\Node;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* 提供一个用于创建节点的资源。
*
* @RestResource(
* id = "rest_resource_post_example",
* label = @Translation("Rest Resource Post Example"),
* uri_paths = {
* "create" = "/rest/api/post/node-create"
* }
* )
*/
class RestResourcePostExample extends ResourceBase {
use StringTranslationTrait;
/**
* 当前用户实例。
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* 构造函数。
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, AccountProxyInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('rest_examples'),
$container->get('current_user')
);
}
/**
* 响应 POST 请求。
*
* 创建一个新的节点。
*/
public function post($data) {
// 验证用户是否有权限。
if (!$this->currentUser->hasPermission('administer site content')) {
throw new AccessDeniedHttpException('访问被拒绝。');
}
foreach ($data as $key => $value) {
$node = Node::create(
[
'type' => $value['nodetype'],
'title' => $value['title'],
'body' => [
'summary' => '',
'value' => $value['body'],
'format' => 'full_html',
],
]
);
$node->enforceIsNew();
$node->save();
$this->logger->notice($this->t("Node with nid @nid saved!\n", ['@nid' => $node->id()]));
$nodes[] = $node->id();
}
$message = $this->t("新节点已创建,nid : @message", ['@message' => implode(",", $nodes)]);
return new ResourceResponse($message, 200);
}
}
用于创建节点的 JSON 示例数据:
[
{
"nodetype": "article",
"title": "培训",
"body": "Cum sociis natoque penatibus..."
},
{
"nodetype": "page",
"title": "团队建设",
"body": "Integer tincidunt ante vel ipsum..."
},
{
"nodetype": "article",
"title": "服务",
"body": "Proin interdum mauris non ligula..."
},
{
"nodetype": "page",
"title": "产品管理",
"body": "Cras mi pede, malesuada in..."
},
{
"nodetype": "article",
"title": "业务发展",
"body": "Nullam porttitor lacus at turpis..."
}
]
发送 POST 请求的 Curl 命令:
curl \
--user uname:password \
--header 'Accept: application/json' \
--header 'Content-type: application/json' \
--request POST http://example.com/rest/api/post/node-create \
--data-binary @post_data.json
文章来源:Drupal 文档。