Crear contenido mediante RESTFull y autentificación básica en Drupal 8

19/02/2019
Enviado por pepem el Dom, 30/09/2018 - 18:44

Activando módulos en el core de Drupal 8

Drupal 8 dispone de una REST Full api en su core, que podemos usar activando los siguientes módulos:

 

El módulo Rate Limiter y el REST UI, no vienen en el core, hay que instalarlos. El Rate Limiter es opcional y no entraré en detalles con él, la descripción del módulo habla por si sola. Sin embargo el módulo REST UI, es imprescindible instalar.

También puedes obtener más información en la documentación oficial https://www.drupal.org/docs/8/api/restful-web-services-api/restful-web-services-api-overview#practical y aquí https://www.drupal.org/docs/8/core/modules/rest/1-getting-started-rest-configuration-rest-request-fundamentals#configuration

Configuración y permisos

Recomendable crear un nuevo Rol, vamos a llamarlo "REST", al que otorgaremos los permisos que necesitemos sobre el tipo de contenido que vamos a trabajar. En mi ejemplo, el tipo de contenido se llama: "Centro". Al ser un test, y descartar que me entorpecieran problemas de permisos, di todos los que había a este rol sobre el tipo de contenido, salvo los de revisiones que no los iba a necesitar. En un sitio en producción esto no debe ser así, y solo otorgar los permisos justos y necesarios.

También comprobaremos que el usuario Admin tiene los permisos suficientes para operar sobre el módulo "RESTful Web Services".

Por último, y el más importante, vamos a Configuración / Rest (Configure Rest server settings). Aquí es donde activamos los servicios que necesitemos. En mi caso, necesito operar sobre contenido. Entonces, activo el resource name "Contenido" y establezco los parámetros que necesito. En mi caso, activo todos los verbos o métodos, todos los formatos posibles y como autenticación "basic_auth".

Probando el servicio desde consola

Lo primero, obtener un token que nos de acceso al servicio. La cadena alfanumérica que devuelva esta llamada (token), la usaremos después en el POST.

Desde consola:

Obtener token:

curl --request GET --url http://<tusitio>/rest/session/token --header 'accept: text/plain'

Para crear el contenido, de tipo centro:

curl --include \
  --request POST \
  --user rest:rest \
  --header 'Content-type: application/hal+json' \
  --header 'X-CSRF-Token: <tutoken>' \
  http://<tusitio>/entity/node?_format=hal_json \
  --data-binary '{"_links":{"type":{"href":"http://<tusitio>/rest/type/node/centro"}},"title":[{"value":"Example node title"}]}'

Aquí dispones de ejemplos en la documentación oficial de Drupal.
https://www.drupal.org/docs/8/core/modules/rest/3-post-for-creating-content-entities#test

Consumiendo el servicio Rest con Python

Para crear nuevo contenido:

import requests

#Get CSRF token
token = str(requests.get('http://tusitio/rest/session/token').text)

endpoint = 'http://tusitio/node?_format=hal_json'

#Set all required headers
headers = {'Content-Type':'application/hal+json',
    'X-CSRF-Token':token
}

#Include all fields required by the content type
payload = '''{
    "_links": {
      "type": {
        "href": "http://tusitio/rest/type/node/centro"
      }
    },
    "title":[{"value":"Esto es una prueba"}]
    }'''

#Post the new node (a Contact) to the endpoint.
r = requests.post(endpoint, data=payload, headers=headers, auth=('rest','rest'))

#Check was a success 
if r.status_code == 201:
    print "Success"
else:
    print "Fail"
    print r

 

Para editar contenido. Nota como cambia el endpoint, como se indica el ID del nodo a modificar en el mismo endpoint y los verbos, en este caso PATCH.

import requests

#Get CSRF token
token = str(requests.get('http://drupal8.local/rest/session/token').text)

endpoint = 'http://drupal8.local/node/52?_format=hal_json'

#Set all required headers
headers = {'Content-Type':'application/hal+json',
    'X-CSRF-Token':token
}

#Include all fields required by the content type
payload = '''{
    "_links": {
      "type": {
        "href": "http://drupal8.local/rest/type/node/centro"
      }
    },
    "title":[{"value":"Esto es una prueba"}],
    "field_nombre_centro":[{"value":"Texto aqui"}]
    }'''

#Post the new node (a Contact) to the endpoint.
r = requests.patch(endpoint, data=payload, headers=headers, auth=('rest','rest'))

#Check was a success 
if r.status_code == 200:
    print "Success"
else:
    print "Fail"
    print r