Pour les besoins d'une de mes formations, j'ai dû mettre en place un drupal 8 découplé.
CORS (Cross-origin resource sharing)
Le « partage de ressources entre origines multiples » (Cross-Origin Resource Sharing, CORS) est désactivé par défaut dans drupal 8.
Pour régler cela : 2 actions :
- sur le serveur apache
-
sudo a2enmod headers
- Dans le fichier de conf d'apache (/etc/apache2/sites-available/mysite.conf :
-
<VirtualHost *:80> ServerAdmin admin@example.com ServerName local.d8-json.my DocumentRoot /home/yvan/dev/d8-json/web ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <Directory /home/yvan/dev/d8-json/web> Options Indexes FollowSymLinks AllowOverride All Require all granted Header set Access-Control-Allow-Origin "*" </Directory>
Puis
sudo a2dissite d8-json.conf sudo systemctl reload apache2 sudo a2ensite d8-json.conf sudo systemctl reload apache2
- dans le fichier web/sites/default/services.yml :
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token', 'authorization', 'content-type', 'accept', 'origin', 'x-requested-with']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['POST', 'GET', 'OPTIONS', 'DELETE', 'PUT', 'PATCH']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: false
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: false
Le front-office sera fait uniquement en js et css et le back office est drupal 8.
Côté Drupal
-
activer les modules du coeur dans la catégorie "Web Services"
-
HAL
- HTTP Basic Authentification
- RESTful Web Services
- Serialization
-
- le module contrib
- REST UI
- Créer un module custom Ex : test_rest dans lequel j'ai créé
- le fichier test_rest.info.yml :
name: test_rest description: 'Test rest package: Coopernet type: module version: 1.0 core: 8.x dependencies: - drupal:node - drupal:path - drupal:text
- le fichier web/modules/custom/test_rest/src/Plugin/rest/resource/ListArticles.php
<?php namespace Drupal\test_rest\Plugin\rest\resource; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\ResourceResponse; /** * Provides a Demo Resource * * @RestResource( * id = "list_articles", * label = @Translation("Articles Resource"), * uri_paths = { * "canonical" = "/test_rest/list_articles" * } * ) */ class ListCartes extends ResourceBase { /** * Responds to entity GET requests. * @return \Drupal\rest\ResourceResponse */ public function get() { $response = ['message' => 'Liste des articles bientôt !!!']; return new ResourceResponse($response); } }
- puis activer le point d'entrée (endpoint) de la ressource, en l'occurence "Articles Resource" dans l'interface de REST UI (/admin/config/services/rest) en donnant tous les droits nécessaires
- enfin, faire appel à ce point d'entrée vial js :
(function() { console.log("Hello"); // création de la requête const req = new XMLHttpRequest(); function enCours(event) { // On teste directement le status de notre instance de XMLHttpRequest if (this.status === 200) { // Tout baigne, voici le contenu de la réponse console.log("Contenu", this.responseText); } else { // On y est pas encore, voici le statut actuel console.log("Statut actuel", this.status, this.statusText); } } req.onload = enCours; // ouverture de la requête //req.open("GET", "/node/3?_format=hal_json", true); req.open("GET", "/memo/list_cartes?_format=json", true); // en complément req.setRequestHeader("Content-Type", "application/hal+json"); // envoi de la requête req.send(null); })();
- Par défaut le super utilisateur est autorisé à obtenir des données via tous les points d'entrée (endpoint) mais si vous souhaitez donner l'accès à d'autres utilisateurs, il faudra vous rendre sur l'interface classique des droits de drupal et gérer chaque accès (rubrique "RESTful Web Services")
Problèmes rencontrés
Status 422
Failed to load resource: the server responded with a status of 422 (Unprocessable Entity)
rest/type/node/article does not correspond to an entity on this site
Solution : vider les caches : drush cr source : https://www.drupal.org/project/restui/issues/2599364
error 404 - No route found for "POST ...
Dans le cas d'une requête post, attention à ajouter une deuxième ligne concernant uri_paths :
uri_paths = {
* "canonical" = "/foolzz_rest_api/profile/{uid}",
* "https://www.drupal.org/link-relations/create" = "/foolzz_rest_api/profile/{uid}"
* }
- Log in to post comments