Drupal 8.3 自定义 Rest POST 错误 BadRequestHttpException:必须指定类型 link 关系

Drupal 8.3 Custom Rest POST Error BadRequestHttpException: The type link relation must be specified

我尝试在我的 Drupal 8.3.2 中创建一个自定义 REST POST 插件以获得外部 JSON,然后从中创建一篇文章。

我已遵循该指南:How to create Custom Rest Resources for POST methods in Drupal 8 这是我的代码:

<?php

namespace Drupal\import_json_test\Plugin\rest\resource;

use Drupal\Core\Session\AccountProxyInterface;
use Drupal\node\Entity\Node;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;

/**
 * Provides a resource to get view modes by entity and bundle.
 *
 * @RestResource(
 *   id = "tio_rest_json_source",
 *   label = @Translation("Tio rest json source"),
 *   serialization_class = "Drupal\node\Entity\Node",
 *   uri_paths = {
 *     "canonical" = "/api/custom/",
 *     "https://www.drupal.org/link-relations/create" = "/api/custom"
 *   }
 * )
 */
class TioRestJsonSource extends ResourceBase {

  /**
  * A current user instance.
  *
  * @var \Drupal\Core\Session\AccountProxyInterface
  */
  protected $currentUser;

  /**
  * Constructs a new TioRestJsonSource object.
  *
  * @param array $configuration
  *   A configuration array containing information about the plugin 
  instance.
  * @param string $plugin_id
  *   The plugin_id for the plugin instance.
  * @param mixed $plugin_definition
  *   The plugin implementation definition.
  * @param array $serializer_formats
  *   The available serialization formats.
  * @param \Psr\Log\LoggerInterface $logger
  *   A logger instance.
  * @param \Drupal\Core\Session\AccountProxyInterface $current_user
  *   A current user instance.
  */
  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('import_json_test'),
     $container->get('current_user')
   );
 }

 /**
  * Responds to POST requests.
  *
  * Returns a list of bundles for specified entity.
  *
  * @param $data
  * 
  * @param $node_type
  *
  * @return \Drupal\rest\ResourceResponse
  *
  * @throws \Symfony\Component\HttpKernel\Exception\HttpException
  *   Throws exception expected.
  */
  public function post($node_type, $data) {

   // You must to implement the logic of your REST Resource here.
   // Use current user after pass authentication to validate access.
   if (!$this->currentUser->hasPermission('access content')) {
     throw new AccessDeniedHttpException();
   }

   $node = Node::create(
       array(
           'type' => $node_type,
           'title' => $data->title->value,
           'body' => [
               'summary' => '',
               'value' => $data->body->value,
               'format' => 'full_html',
               ],
           )
   );

   $node->save();
   return new ResourceResponse($node);

 }

}

现在,如果我尝试在不传递有效载荷的情况下进行测试并以这种方式修改 return 值:

return new ResourceResponse(array('test'=>'OK'));

有效!

但是如果我使用上面的自定义代码发送这样的自定义负载:

 {
 "title": [{
   "value": "Test Article custom rest"
 }],
 "type": [{
   "target_id": "article"
 }],
 "body": [{"value": "article test custom"}]
}

我收到 400 错误:Symfony\Component\HttpKernel\Exception\BadRequestHttpException:必须指定类型 link 关系。在 Drupal\rest\RequestHandler->handle() 中(core/modules/rest/src/RequestHandler.php 的第 103 行)。

怎么了?

谢谢。

我找到了解决方案:

我删除了注释:

*   serialization_class = "Drupal\node\Entity\Node",

然后我只关心 post 函数中的数据:

  /**
  * Responds to POST requests.
  *
  * Returns a list of bundles for specified entity.
  *
  * @param $data
  *
  *
  * @return \Drupal\rest\ResourceResponse
  *
  * @throws \Symfony\Component\HttpKernel\Exception\HttpException
  *   Throws exception expected.
  */
 public function post($data) {

   // You must to implement the logic of your REST Resource here.
   // Use current user after pass authentication to validate access.
   if (!$this->currentUser->hasPermission('access content')) {
     throw new AccessDeniedHttpException();
   }


   return new ResourceResponse(var_dump($data));

重要的是,当你使用 postman 时,添加一个 header 和 Content-Type -> application/json:

而不是 Content-Type -> application/hal+json

使用此配置,我可以 post 任何类型的 JSON,然后按我喜欢的方式进行管理。

再见!