Create Once, Publish Everywhere with API-First Drupal

DrupalのJSON:API入門

DrupalをContent as a Service(CaaS)として活用する上で欠かせない「JSON:API」モジュールの概要から使い方、既存のREST APIとの違いなど、JSON:APIを使用してシステム間でデータを渡す方法についてご紹介します。

過去にウェビナーでも取り上げた内容です。同内容を動画でもご覧いただけます。

ウェビナーでも取り上げた内容です。

DrupalはAPI-First、ヘッドレスアーキテクチャに力を入れている!

まず世の中のトレンド変化として、スマートフォンアプリ、スマートウォッチ、IoT機器、スマートスピーカー、デジタルサイネージが登場し、Drupalが誕生した2000年当初では、CMSはHTMLファイルを吐き出すだけだったものが、今では同じデータをマルチチャネルに配信する基盤やソリューションが求めれています。

また技術的なトレンドとして、React、Vue、Angularなどの強力なJavaScriptフレームワークの登場により、複雑で大規模なアプリが構築できるようになりました。JavaScriptはプログラミング言語ランキングでも数年前から首位をキープしており、JavaScriptエンジニアの市場は急速に成長し続けています。

チャネルの増加とJavaScriptの人気に対して、Drupalは「API-First」を掲げて最高の構造化データエンジンおよびWebサービスプラットフォームに対応させる取り組みが始まっています。

Drupalでは、さまざまなWebサイトやサービスのコンテンツを1つの場所で管理し、マルチチャネルにデプロイすることが可能です。これはデカップルド・アーキテクチャ(Decoupled Architecture)およびヘッドレス(Headless)と呼ばれ、DrupalをヘッドレスCMSとして、モダンなJavaScriptアプリケーションはもちろんのこと、静的サイトジェネレーターとの組み合わせ(JAMStack)、チャットボット、スマートスピーカーなどで活用することができます。

DrupalのWeb API

Drupalでは、コア機能に「RESTful Web Services」と「JSON:API」という二つのREST APIが存在します。どちらもコアモジュールでREST形式ということで、一体何が違うのか最初は私も疑問に思いました。

どちらを使うべきなのか、公式ドキュメント では以下のように説明されています。

 

Choose REST if you have non-entity data you want to expose. In all other cases, choose JSON:API.

(公開するエンティティ以外のデータがある場合は、RESTを選択します。それ以外の場合はすべて、JSON:APIを選択します。)

 

JSON:APIは、従来のRESTful Web Servicesよりもシンプルに簡単にAPIを扱えることが特徴です。DrupalのコンテンツやユーザーデータなどをJSONでGET、POSTするならばおおよそJSON:APIを利用できます。

REST形式の他に、コアモジュールではないですが、コントリビュートモジュールとして公開されている「GraphQL」モジュールも非常に人気です。

JSON:API とは

JSON:APIは2016年から開発が開始され、Drupal 8.7で安定版としてコアモジュールに導入されました。JSONでAPIを作成するためのオープンスタンダードな仕様「JSON API」に準拠しており、共有された規約に従うことでRESTful APIを迅速かつ一貫して作成することが可能になります。

モジュールを有効化する

DrupalでJSON:APIを使い始めるには、まずJSON:APIの利用に必要なコアモジュールを有効にする必要があります。管理画面の拡張機能ページにて、以下2つのモジュールにチェックを入れ、インストールします。

 

json api drupal

 

  • JSON:API:エンティティをJSON:API仕様に準拠したWeb APIとして公開します。
  • Serialization:JSON、XMLなどの形式との間でデータをシリアライズします。

JSON:API のURL構造

まず手始めに、JSON:APIのエントリポイント(/jsonapi)にGETリクエストを送信してみます。全てのリソースが配置されている場所を示すリンクのリストが表示されます。

$ curl http://drupal-9-project-9-0-1.dd:8083/jsonapi
{
    "jsonapi": {
        "version": "1.0",
        "meta": {
            "links": {
                "self": {
                    "href": "<http://jsonapi.org/format/1.0/>"
                }
            }
        }
    },
    "data": [],
    "links": {
        "action--action": {
            "href": "<http://drupal-9-project-9-0-1.dd:8083/jsonapi/action/action>"
        },
        "base_field_override--base_field_override": {
            "href": "<http://drupal-9-project-9-0-1.dd:8083/jsonapi/base_field_override/base_field_override>"
        },
        "block--block": {
            "href": "<http://drupal-9-project-9-0-1.dd:8083/jsonapi/block/block>"
        },
        "block_content--basic": {
            "href": "<http://drupal-9-project-9-0-1.dd:8083/jsonapi/block_content/basic>"
        },

...(省略)...

リソースの指定方法は、次のパターンに従います。

/jsonapi/{entity_type_id}/{bundle_id}[/{entity_id}]

以下はリソース取得の一例です。

  • /jsonapi/node/article ...全ての記事(article)リソースを取得
  • /jsonapi/node/article/xxx ...UUID=xxx の記事を取得
  • /jsonapi/node/article/xxx/uid ...記事(UUID=xxx)と紐付く投稿者(ユーザー)リソースを取得

JSON:API の CRUD オペレーション

JSON:APIで受け付けるHTTPメソッドは以下の4種類で、PUTは未対応です。GETのみ複数リソースを扱うことができます。

メソッド 説明
GET リソースの取得(単一 or 複数)
POST 新しいリソースを作成
PATCH 既存のリソースの更新
DELETE 既存のリソースの削除

高度なリソース取得方法

その1. フィルタリング

記事一覧から、タイトルが「react」に完全一致する記事を絞り込む場合の例です。直感的で非常にシンプルに指定できます。

GET /jsonapi/node/article?filter[title]=react

実は上記は、次のように指定することもできます。 path は絞り込み対象のフィールドを指定します。 operator は比較方法を指定します。 label-a でKey-Valueをグループ化します。

GET /jsonapi/node/article?filter[label-a][condition][path]=title
                         &filter[label-a][condition][operator]=%3D  <- "="のエンコード
                         &filter[label-a][condition][value]=react

こちらは完全一致ではなく「react」が含まれるタイトルで絞り込む場合の例です。

GET /jsonapi/node/article?filter[label-a][condition][path]=title
                         &filter[label-a][condition][operator]=CONTAINS
                         &filter[label-a][condition][value]=react

その2. ソート

タイトルを昇順でソートする例です。

GET /jsonapi/node/article?sort[sort-title][path]=title

降順でソートする場合は次のようになります。

GET /jsonapi/node/article?sort[sort-title][path]=title
                         &sort[sort-title][direction]=DESC

その3. ページネーション

記事が100件、1,000件存在するような、一度のリクエストで取ってこれない場合にページネーションを使って、10ページずつ取得する例です。

GET /jsonapi/node/article?page[offset]=20
                         &page[limit]=10

ReactとDrupalのデモアプリ

ここまで基本的なJSON:APIの使い方を紹介しました。実際にJSON:APIを使用して、バックエンドにDrupal、フロントエンドにReactが採用されたサンプルアプリがDrupalize.meのgihubリポジトリに掲載されていたので、ここで紹介します。

https://github.com/DrupalizeMe/react-and-drupal-examples

APIの認証方法など参考にできる部分がたくさんあると思います。

最後に

DrupalのWeb APIが非常にアツいです!ぜひみなさんもDrupalをCMSとしてだけではなくAPIサーバーとしてもご活用ください。

丸山 ひかる

Technical Translator Acquia

アクイアの日本リージョンにて、テクニカルトランスレーターとしてウェブサイトのコンテンツの技術翻訳やローカライズを担当しています。ソフトウェアエンジニアとして5年以上の就業経験を持ちます。また、AWS Certified Solutions Architect、Certified Scrum Product Owner、そしてCertified ScrumMasterの資格を保有します。