Drupal 8 Rest Json

Integracja z prostą aplikacją w JavaScript

W ostatnich latach serwisy internetowe bardzo się zmieniły. Powstało wiele nowych usług i serwisów społecznościowych. Dużą rolę w internecie odgrywają obecnie aplikacje mobilne. Wymiana danych między serwisami internetowymi to już nic dziwnego. Integrację z usługami zewnętrznymi to norma, szczególnie w przypadku dużych aplikacji e-commerce czy systemach płatności online.

Tu nasuwa sie pytanie: czy używając Drupala możemy komunikować się z usługami zewnętrznymi? Jako drupalowa agencja w ramach naszych prac Drupal developmentu bardzo często zajmujemy się integrowaniem JavaScript z różnymi aplikacjami. Dlatego na zadane pytanie możemy odpowiedzieć: oczywiście że tak! Możliwe było to także w starszych wersjach Drupala. Jednak w wersji 8 moduł RESTful Web Services API jest domyślnie dołączony do rdzenia systemu, co pokazuje, że jest to ważny i potrzebny element w rozbudowanych aplikacjach internetowych.

Dzisiaj omówimy jeden z popularniejszych formatów wymiany danych jakim jest mianowicie JSON.


W naszym przykładzie użyjemy Drupala w wersji 8.2^ oraz jQuery do napisania prostej aplikacji w języku JavaScript. Drupala wykorzystamy jako nasz CMS do zarządzania danymi, natomiast treści będziemy wyświetlać na "lekkiej" stronie wykonanej w HTML.

1. Instalujemy Drupala 8 oraz włączamy moduły:

  • The RESTful Web Services API is new in Drupal 8
  • Serialization

moduł REST/JSON Drupal 8

2. Ściągamy i włączamy moduł REST UI (Opcjonalne, ale przydatne).

https://www.drupal.org/project/restui

Moduł ten pozwala z poziomu interfejsu użytkownika (panel administracyjny) sterować dostępem oraz formatem danym. (działa z wersją Drupala 8.2 w górę).

3. Konfiguracja przez REST UI - wyświetlanie noda w formacie JSON.

Dostosujemy nasz rodzaj zawartości do integracji. W naszym przykładzie użyjemy encji NODE. Wchodzimy /admin/config/services/rest. Wybieramy "content type" i ustawiamy w metodzie GET: format json, auth cookie. W naszym przykładzie będziemy jedynie pobierać dane, więc GET wystarczy.

Drupal 8 - Moduł Rest UI

 

Jeżeli nie mamy modułu REST UI, musimy ręcznie w configach wprowadzić ustawienia dla danych encji. Powyższe ustawienia wyglądają tak:

Nazwa pliku: rest.resource.entity.node.yml

uuid: add2fdec-b11f-45ad-a74f-3d30e36ad72f
langcode: en
status: true
dependencies:
  module:
    - node
    - serialization
    - user
id: entity.node
plugin_id: 'entity:node'
granularity: method
configuration:
  GET:
    supported_formats:
      - json
    supported_auth:
      - cookie


4. Utwórzmy teraz naszego noda.

Zakładając że nasz nowy node jest pod adresem http://www.drupal8.dev/node/1
dodajemy parametr ?_format=json co daje nam adres: domena.example/node/1?_format=json 

Jeżeli wszystko zrobiliśmy dobrze to powinniśmy otrzymać obiekt node w formacie JSON . Jeżeli często wyświetlacie format JSON w przeglądarce można zainstalować dodatek do przeglądarki formatujący kod JSON (ten co widać na screenie to JSON Lite https://addons.mozilla.org/en-US/firefox/addon/json-lite/?src=api)

Node w formacie JSON

5. Lista nodów w JSON

Pobieranie pojedynczych treści (nodów) już nam działa. Spróbujmy teraz uzyskać listę treści (nodów).
Użyjemy do tego modułu Views.

Views - tworzenie

 

Jeżeli nie będziemy używać większości dostępnych danych, możemy wybrać tylko interesujące nas pola, aby zmniejszyć ilość przesyłanych danych.

Views - konfiguracja views JSON

Podsumowując: stworzyliśmy listę z naszymi treściami pod adresem /node_list oraz dodając do url ?=_format=json możemy pobrać dowolny z formacie json.

6. Własny adres dla REST/JSON (endpoint)

Jeżeli z jakiś powodów rozwiązania powyżej nam nie wystarczają, możemy napisać swój endpoint i dostarczyć inne dane do naszego JSONa.

Stworzymy routing oraz controller.

Routing

Zaczniemy od stworzenia routingu np pod adresem /v1/custom_endpoint. Dobrą praktyka jest wpisywanie wersji naszego API w URL. Jeżeli stworzymy nowszą wersje za jakiś czas utworzymy ją pod adresem v2/custom_endpoint, v3 itp. Przez co użytkownicy, którzy korzystają ze starszego API nie zostaną odcięci od naszych zasobów.

Przykład: routingu

ev_client_endpoint:
  path: '/v1/custom_endpoint'
  methods:  [GET]
  defaults:
    _controller: 'Drupal\ev_client_endpoint\Controller\EvEndpoint::get'
  requirements:
    _permission: 'access content'

Czyli: wywołując GET na url /v1/custom_endpoint dostaniemy dane, które zwróci nam controller EvEndpoint wykonując metodę GET.

 

Controller

Dla przykładu załóżmy, że nasz endpoint ma zwrócić podstawowe informacje o naszej stronie: nazwę i email, aktualny timestamp oraz losowy node z id od 1 do 10.

<?php

namespace Drupal\ev_client_endpoint\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * An example controller.
 */
class EvEndpoint extends ControllerBase {

  /**
   * {@inheritdoc}
   */
  public function get() {

    $response = new JsonResponse();
    $config = \Drupal::config('system.site');
    $node = Node::load(random_int(1,10));
    $data = array(
      'date' => time(),
      'site_name' => $config->get('name'),
      'site_email' => $config->get('mail'),
      'random_node' => array(
        'title' => $node->get('title')->getValue()[0]['value'],
        'body' => $node->get('body')->getValue()[0]['value'],
      )
    );

    $response->setData($data);

    return $response;

  }
}

Jeżeli wszystko zrobiliśmy, czyścimy cache i wchodzimy na stronę /v1/custom_endpoint, powinniśmy otrzymać coś takiego.

{
"date": 1481920261,
"site_name": "custom endpoint site",
"site_email": "admin@examplesite",
"random_node": {
"title": "title node 5",
"body": "body node 5"
}
}

 

7. Odbieranie JSON

Stworzymy prosty skrypt JS, który wyświetli nasz dane na stronie.

Jeżeli będziemy łączyć się z innych domen niż nasz Drupal, przyda się także moduł https://www.drupal.org/project/cors lub dodanie nagłówków do zapytań, ewentualnie stworzenie wirtualnego proxy, aby zapytania były widziane jako lokalne (więcej na https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS )

 

Kod html index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="app.js"></script>
</head>
<body>

</body>
</html>

W sekcji Head dodajemy nasz plik app.js oraz bibliotekę jQuery

Skrypt app.js

$(document).ready(function () {
  $.ajax({
    type: 'GET',
    url: 'http://drupal8.dev/v1/custom_endpoint',
    success: function (data) {
      {
        var date = new Date(data.date * 1000);
        $('body').append('' +
          '<h1 class="name">' + data.random_node.title + '</h1>' +
          '<content class="body">' + data.random_node.body + '</content>' +
          '<email class="mail">' + data.site_email + '</email>' +
          '<div class="date">' + date  + '</div>' +
          '<h2 class="email">' + data.site_name + '</h2>'
        );
      }
    }
  });
});

Pobieramy JSON z naszego Drupala : v1/custom_endpoint

W zmiennej data zawiera się nasz odebrany json, funkcją append dodajemy do body html z naszymi zmiennymi.

Jeżeli wszystko działa dobrze to wyświetlając w przeglądarce stronę index.html skrypt JS pobiera z naszego Drupala dane w formacie JSON oraz dodaje je w body.

 

Podsumowanie

Są to podstawowe informacje jak zacząć przygodę z web services przy użyciu Drupala. W następnej części opiszemy jak zalogować się do Drupala za pomocą istniejącego konta użytkownika oraz jak dodawać i edytować zawartości poprzez REST/JSON.

Jeżeli chcesz dalej zgłębiać wiedzę na temat ósemki oraz innych narzędzi przydatnych przy projektowaniu aplikacji webowych, polub nas na Facebooku gdzie udostępniamy tutoriale, poradniki oraz ciekawostki z branży, bierz udział w Drupal Day oraz Drupal Camp! Już niebawem następne nowości u nas na blogu.

 

3. Najlepsze praktyki zespołów programistycznych