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
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.
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)
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.
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.
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.