Drupal 8.3自定义休息POST错误BadRequestHttpException:必须指定类型链接关系

时间:2017-05-17 09:14:45

标签: php json rest drupal-modules drupal-8

我尝试在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 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:必须指定类型链接关系。在Drupal \ rest \ RequestHandler-&gt; handle()(core / modules / rest / src / RequestHandler.php第103行)。

出错了什么?

THX。

1 个答案:

答案 0 :(得分:3)

我找到了解决方案:

我删除了注释:

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

然后我只关注我的帖子功能中的数据:

  /**
  * 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));

重要的是,当您使用邮递员时,例如,添加内容类型的标题 - &gt;应用程序/ JSON: THe header configuration in postman

取代Content-Type - &gt;应用/ HAL + JSON

使用此配置,我可以发布任何类型的JSON,然后根据需要进行管理。

再见!