Adobe Commerce / Magento Open Sourceで独自のREST APIエンドポイントを作成するには〜その1

今回は、Adobe Commerce / Magento Open Sourceで独自のREST APIエンドポイントを作成する方法をご紹介します。
REST APIエンドポイントを増やすことで、標準のエンドポイントではカバーできない領域のデータ連携を実現できます。

はじめに

この記事では、「Adobe Commerce / Magento Open Sourceのエクステンションの作り方」については触れません。
エクステンションの作成方法、特にModelやInterfaceを使用した実装について理解がある方を前提にしています。

REST APIの作成手順

Adobe Commerce / Magento Open SourceでREST APIを定義するには、以下の手順に沿って行います。

  • webapi.xmlの作成
  • APIに使用する各種Interfaceの定義
  • Interfaceを実装したModelクラスの定義

今回は最初のwebapi.xmlについて解説したいと思います。

webapi.xmlとは

webapi.xmlは、Magentoフレームワークにおいて、REST / SOAP APIエンドポイントを定義するために使用するXMLファイルです。

  • インストールディレクトリ/vendor/magento/module-webapi/etc/webapi.xsd
  • インストールディレクトリ/vendor/magento/module-webapi/etc/webapi_base.xsd
  • インストールディレクトリ/vendor/magento/module-webapi/etc/webapi_merged.xsd

にXSDが用意されています。
タグの定義に迷った場合は、これらのXSDを参照するとよいでしょう。

webapi.xmlの配置場所

webapi.xmlは、

エクステンションディレクトリ/etc/webapi.xml

に配置します。
frontendやadminhtmlディレクトリがetcディレクトリ配下にはありますが、webapi.xmlは常にグローバルスコープでしか配置できません。
config.xmlやmodule.xmlと同様です。

webapi.xmlに記述する内容

webapi.xmlには以下の内容を記述します。

  • REST APIエンドポイントパス
  • HTTPメソッド
  • エンドポイントの対になるサービスインターフェイス名とメソッド名
  • このエンドポイントを利用可能な権限
  • REST API側が使用するパラメータ名

タグ名や属性名はXSDを参照していただければ間違いはありません。
PHPStormの場合は、

  • Magento2プラグインをインストールする
  • php bin/magento dev:urn-catalog:generate を実行し、生成されたファイルを使用する

という方法でXSD定義に基づくタグの入力補完とバリデーションができるようになります。

webapi.xmlの書き方の例

ここからはwebapi.xmlに記述する内容の例を紹介していきましょう。
書き方の例には大きくわけて3種類があります。

  • APIの利用権限を指定しない書き方
  • ログイン中の本人に限定する書き方
  • API権限に基づく制限を設ける書き方

APIの利用権限を指定しない書き方

まずはAPIの利用権限を設定しない書き方です。
代表的な例としては、ゲスト時の購入画面に使用されるAPIがあります。例えば以下のような定義です。

    <route url="/V1/guest-carts/:cartId/shipping-information" method="POST">
        <service class="Magento\Checkout\Api\GuestShippingInformationManagementInterface" method="saveAddressInformation"/>
        <resources>
            <resource ref="anonymous" />
        </resources>
    </route>

この書き方の場合、resourceタグに「anonymous」を指定しています。
「anonymous」つまりは「匿名」ということなので、このAPIには誰でもアクセスできてしまいます。

ただし、この例ではrouteタグのurl属性で指定しているURLに「:cartId」という動的なパラメータがあります。
このパラメータをJS側で以下のような書き方で動的に置換することで、この値を知り得るゲストにだけ許可を与えることができます。

    serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/payment-information', {
      cartId: quote.getQuoteId()
  });

なお、「cartId」として使用される値については、Magentoフレームワーク内でランダムな文字列が発行されます。
データベース上で自動採番しているIDがそのまま使われることはありません。

ログイン中の本人に限定する書き方

次はログイン中の本人にだけ権限を与える書き方です。
この書き方も購入画面で使用されています。

    <route url="/V1/carts/mine/shipping-information" method="POST">
        <service class="Magento\Checkout\Api\ShippingInformationManagementInterface" method="saveAddressInformation"/>
        <resources>
            <resource ref="self" />
        </resources>
        <data>
            <parameter name="cartId" force="true">%cart_id%</parameter>
        </data>
    </route>

この書き方の場合、先程のゲスト用のようにURL内にパラメータを埋める部分はありません。
代わりにdataタグの子要素として、parameterタグで必要なパラメータ名を宣言します。
ここで宣言したパラメータは、serviceタグで定義したインターフェイスのメソッドに渡されます。

またこの書き方では、resourceタグのref属性に「self」を指定しています。こうすることでAPIのアクセス範囲を該当のアクセスをしてきた本人に限定することができます。

API権限に基づく制限を設ける書き方

最後はシステム連携向けのAPI権限に基づく書き方です。
前2つの書き方から大きく変わる部分はありませんが、以下のように定義を行います。

    <route url="/V1/customerGroups/:id" method="GET">
        <service class="Magento\Customer\Api\GroupRepositoryInterface" method="getById"/>
        <resources>
            <resource ref="Magento_Customer::group"/>
        </resources>
    </route>

この例では、resourceタグの「ref」属性で管理者権限を指定しています。
ここで指定する権限の名称は、acl.xmlで定義されています。

この書き方をした場合は、該当の権限を持っていることが不可欠になるため、APIを利用する前に認証処理が必要になります。
APIの認証処理については、

で触れています。

まとめ

ここまでの内容をまとめましょう。

  • Adobe Commerce / Magento Open SourceでREST APIを独自定義したい場合には、webapi.xmlを作成する
  • 定義できるAPIの権限には3種類がある
  • API権限を利用する場合は、acl.xmlの定義内容を参照する

というものです。
次回はserviceタグで定義したInterfaceとそれを実装するクラスについて説明していきたいと思います。