
Drupal 8: Creando un recurso REST personalizado con un método POST
Autor: fjavimartin
Fecha de Creación: 11/05/2019
Categorías:
En esta entrada de blog ampliaremos el controlador que implementamos en el último artículo añadiendo un nuevo método que nos permitirá crear un nuevo nodo de tipo article mediante una llamada POST a un recurso REST y devolveremos la entidad creada como un json.
1. Añadir ruta al routing.yml
Al igual que es nuestro último artículo tendremos que añadir la ruta a nuestro fichero routing.yml modificando el método autorizado para acceder a ella:
drupal_miseries.customrestpost:
path: '/drupal_miseries/rest/customrestpost'
defaults:
_controller: '\Drupal\drupal_miseries\Rest\CustomRest::createNode'
methods: [POST]
requirements:
_access: 'TRUE'
En esta ocasión crearemos una nueva entidad al acceder a este endpoint por lo que el método que utilizaremos será POST.
2. Servicio Serializer
Drupal, que es como una pequeña navaja suiza, nos ofrece en su core todas las herramientas necesarias para que no tengamos que buscarnos las vida fuera de su entorno para hacer casi nada. En nuestro artículo vamos a devolver el nodo que creemos en formato json por lo que tendremos que serializarlo, es decir, lo devolveremos como si fuera una cadena de texto.
El módulo serialization nos aporta las funciones necesarias para serializar y deserializar datos en formatos json y xml. Necesitaremos activar este módulo en nuestro sitio drupal y de esta manera dispondremos del servicio serializer que nos suministrará las funciones necesarias.
Una vez instalado el módulo serialization incorporaremos a nuestra clase el servicio serializer mediante la inyección de servicios.
protected $entityTypeManager;
protected $serializer;
/**
* Construct implementation.
* @param EntityTypeManagerInterface $entityTypeManager
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, SerializerInterface $serializer ) {
$this->entityTypeManager = $entityTypeManager;
$this->serializer = $serializer;
}
/**
* Create implementation.
* @param ContainerInterface $container
* @return \Drupal\drupal_miseries\Rest\CustomRest
*/
public static function create(ContainerInterface $container) {
return new static (
$container->get('entity_type.manager'),
$container->get('serializer')
);
}
Una cosa importante que tendremos que tener en cuenta será incluir el módulo serialization
3. Método createNode
El último paso será añadir el método que crea el nuevo nodo con los datos que le pasamos en la llamada al endpoint:
/**
* Create node and returned it serialized as json
* @param Request $request
* @return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function createNode(Request $request) {
$storage = $this->entityTypeManager->getStorage('node');
// Get data value from request
$data = $request->request->get('data');
// Transform json from request to associative array
$values = json_decode($data, true);
// Create node entity
$node = $storage->create([
'type' => $values['node']['type'],
'title' => $values['node']['title'],
'body' => [
'summary' => $values['node']['body']['summary'],
'value' => $values['node']['body']['value'],
'format' => $values['node']['body']['format'],
],
]);
// Save entity
$node->save();
// Encode node as json
$node_encoded = $this->serializer->serialize($node, 'json', ['plugin_id' => 'entity']);
// Build response with node serialized
$response = new JsonResponse([
'node' => $node_encoded,
]);
return $response;
}
En esta ocasión obtenemos los datos necesarios para crear el nuevo nodo de la solicitud que recibimos (Request) y que enviamos en un atributo llamado data en formato json.
Transformamos los datos recibidos en un array asociativo convencional mediante la llamada a la función json_decode para poder trabajar cómodamente.
Con los datos del array anterior creamos la nueva entidad normalemente. El tipo de la entidad, que en nuestro caso será article, es uno de los valores que hemos metido en el array por lo que podríamos crear cualquier tipo de entidad node. Extendiendo este ejemplo podríamos crear cualquier tipo de entidad drupal de la misma forma que estamos creando un node.
Una vez creado el nodo lo salvamos, de otra manera no se almacenará en la base de datos, y lo serializamos haciendo uso del servicio serializer para después construir la respuesta que finalmente devolveremos. En esta ocasión no devolveremos un objeto JsonResponse porque ya tenemos nuestro nodo en formato json por lo que utilizaremos un objeto Response y devolveremos el nodo serializado.
4. Probando nuestro endpoint POST
Para esta serie de artículos estoy utilizando postman, extensión gratuita de chrome que nos permitirá crear las llamadas que queramos, tenerlas almacenadas en todos nuestros dispositivos y utilizarlas en cualquier momento. Os dejo en las referencias el enlace a su web para que le echéis un ojo, pero podéis utilizar cualquier otra extensión para esta tarea.
Para nuestro ejemplo necesitaréis crear un json que será el que configuremos en postman con los datos del article que queremos crear. No preocuparse, yo he utilizado JSON Editor Online que de una manera fácil y sencilla nos permitirá hacer lo que necesitamos para nuestro ejemplo:
{
"node": {
"type": "article",
"title": "Article created by webservice",
"body": {
"summary": "Article summary",
"value": "Article body",
"format": "full_html"
}
}
}
La llamada que he utilizado para probar el endpoint es la siguiente:
POST /drupal_miseries/rest/customrestpost HTTP/1.1
Host: mihost
Cache-Control: no-cache
Postman-Token: 59393cad-3293-0bff-7d80-72da0d36380b
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"
{
"node": {
"type": "article",
"title": "Article created by webservice",
"body": {
"summary": "Article summary",
"value": "Article body",
"format": "full_html"
}
}
}
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Una vez hayamos creado la solicitud en postman solamente tendremos que pinchar en el botón Send para crear nuestro article y si todo ha ido bien recibiremos una respuesta muy parecida a la siguiente:
{"nid":[{"value":197}],"uuid":[{"value":"ccfd3684-922b-46fd-ada4-06f5017b9b5e"}],"vid":[{"value":339}],"langcode":[{"value":"es"}],"type":[{"target_id":"article","target_type":"node_type","target_uuid":"eeda99cd-8e75-4ae1-9333-c2fd165b9acf"}],"status":[{"value":true}],"title":[{"value":"Article created by webservice"}],"uid":[{"target_id":0,"target_type":"user","target_uuid":"fe13a79d-1445-458d-a09a-2a1b14c818d8","url":"\/drupal8\/en\/user\/0"}],"created":[{"value":1557679616}],"changed":[{"value":1557679616}],"promote":[{"value":true}],"sticky":[{"value":false}],"revision_timestamp":[{"value":1557679616}],"revision_uid":[{"target_id":0,"target_type":"user","target_uuid":"fe13a79d-1445-458d-a09a-2a1b14c818d8","url":"\/drupal8\/en\/user\/0"}],"revision_log":[],"revision_translation_affected":[{"value":true}],"default_langcode":[{"value":true}],"path":[],"menu_link":[{"target_id":null}],"content_translation_source":[{"value":"und"}],"content_translation_outdated":[{"value":false}],"body":[{"value":"Article body","format":"full_html","summary":"Article summary"}],"comment":[{"status":2,"cid":0,"last_comment_timestamp":0,"last_comment_name":null,"last_comment_uid":0,"comment_count":0}],"field_articulo_referencia":[],"field_image":[],"field_tags":[]}
Este “troncho” representa en formato json el nodo que acabamos de crear. Si vamos a la sección de contenido de nuestro sitio drupal lo encontraremos en primera posición.
Conclusiones
Con este pequeño ejemplo hemos creado una entidad node de tipo article, pero ya habéis visto que fácil es pasar información vía json en una solicitud POST. Podéis ampliar esta clase para crear cualquier cosa dentro de vuestro sitio drupal.
Disfrutar!!!!!!!!!!
Referencias
https://www.drupal.org/node/2098511
https://www.drupal.org/node/2098511
https://www.e-quipos.es/blog/drupal-8-inyecci%C3%B3n-de-servicios
https://www.drupal.org/docs/8/core/modules/serialization
https://symfony.com/doc/current/introduction/http_fundamentals.html
https://symfony.com/doc/current/components/http_foundation.html
https://www.e-quipos.es/blog/drupal-8-creando-un-recurso-rest-personalizado-con-un-m%C3%A9todo-get