発見

2020.03.24 2020.03.24

TOPICS

クライアントが未知のサイトに話しかけるときは、そのサイトが何ができるのか、そのサイトがどのように設定されているのかを発見する必要があります。
これには、何を発見する必要があるかによって、いくつかのステップがあります。

APIを発見する

サイトに接続する最初のステップは、サイトがAPIを有効にしているかどうかを確認することです。
通常、ユーザー入力の URL を使用することになるので、アクセスしているサイトは何でもよいのです。
発見ステップでは、API が利用可能かどうかを確認するだけでなく、API へのアクセス方法も示します。

リンクヘッダー

発見するためのよい方法は、指定されたアドレスにHEADリクエストを送信することです。
REST APIは、以下のようなLinkヘッダーを、すべてのフロントエンドページに自動的に追加します。

Link: <http://example.com/wp-json/>; rel="https://api.w.org/"

上記のURLは、APIの元となるルートを示しており、そのあとの発見ステップに使用します。

“pretty パーマリンク”を有効にしていないサイトでは、/wp-json/は、WordPressによって自動的に処理されません。
つまり、WordPressのデフォルトのパーマリンクが代わりに使用されます。
ヘッダーは以下のようになります。

pretty パーマリンクとは
検索フレンドリーURL、投稿のタイトルなどの単語を含むURL構造のこと。
管理画面のパーマリンク設定のカスタム構造で設定できます。

Link: <http://example.com/?rest_route=/>; rel="https://api.w.org/"

クライアントはこのパターンを念頭に置き、両方のルートを処理できるようにする必要があります。

この自動検出は、WordPressのインストールによって提供される任意のURLに適用することができるので、ユーザー入力に対する前処理を追加する必要はありません。
これは HEAD リクエストなので、副作用を心配することなく、サーバに送信しても安全です。

要素

HTMLパーサーを持つクライアントやブラウザで実行されているクライアントでは、フロントエンドページの<head><link>要素を介してLinkヘッダーと同等のものが含まれています。

<link rel='https://api.w.org/' href='http://example.com/wp-json/' />

ブラウザに組み込まれているJavaScriptは、このデータにDOMを介してアクセスできます。

// jQuery method
var $link = jQuery( 'link[rel="https://api.w.org/"]' );
var api_root = $link.attr( 'href' );
 
// Native method
var links = document.getElementsByTagName( 'link' );
var link = Array.prototype.filter.call( links, function ( item ) {
    return ( item.rel === 'https://api.w.org/' );
} );
var api_root = link[0].href;

上記の方法は、ブラウザ内のクライアントや HTTP ヘッダにアクセスできないクライアントにとっては、API を発見するためのより使いやすい方法かもしれません。
これは Atom/RSS フィードの発見に似ているので、その目的のための既存のコードも自動的に代わりに適応されました。

RSD (Really Simple Discovery) 

XML-RPC ディスカバリをサポートしているクライアントでは、RSD メソッドの方が適用可能な場合があります。
これは、XML-RPC で一般的に使用される XML ベースのディスカバリーフォーマットです。RSD には 2 つのステップがあります。最初のステップは、 <link>要素として提供される RSD エンドポイントを見つけることです。

<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.com/xmlrpc.php?rsd" />

2 番目のステップは、RSD ドキュメントを取得し、利用可能なエンドポイントを解析することです。これには、以下のようなドキュメント上で XML パーサーを使用する必要があります。

<?xml version="1.0" encoding="utf-8"?>
<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
  <service>
    <engineName>WordPress</engineName>
    <engineLink>https://wordpress.org/</engineLink>
    <homePageLink>http://example.com/</homePageLink>
    <apis>
      <api name="WordPress" blogID="1" preferred="true" apiLink="http://example.com/xmlrpc.php" />
      <!-- ... -->
      <api name="WP-API" blogID="1" preferred="false" apiLink="http://example.com/wp-json/" />
    </apis>
  </service>
</rsd>

REST APIは常にWP-APIと等しい値を持つname属性を持っています。

RSDは、いくつかの理由から、オートディスカバリーの中で最も好まれていない方法です。RSDベースのディスカバリーの最初のステップでは、まずHTMLを解析してRSDドキュメント自体を見つけますが、これは<link>要素の自動ディスカバリーと同じです。次に、RSD文書を解析するための別のステップが必要で、これには完全なXMLパーサーが必要です。

しかし、既存の XML-RPC クライアントが既に RSD パーサーを有効にしている場合は、この方法を使用することをお勧めします。REST API をコードベースの進歩的な拡張として使用したい XML-RPC クライアントでは、異なる形式のディスカバリをサポートする必要がなくなります。

認証方法を見つける

発見は、API を介して利用可能な認証方法についても利用可能です。API ルートのレスポンスは、認証キーを含む API を記述したオブジェクトです。

{
    "name": "Example WordPress Site",
    "description": "YOLO",
    "routes": { ... },
    "authentication": {
        "oauth1": {
            "request": "http://example.com/oauth/request",
            "authorize": "http://example.com/oauth/authorize",
            "access": "http://example.com/oauth/access",
            "version": "0.1"
        }
    }
}

authenticationの値は、認証方法の ID と認証オプションの連想配列です。
ここで使用可能なオプションは、認証方式そのものに固有のものです。特定の認証方法のオプションについては、認証のドキュメントを参照してください。

発見の拡張

APIを発見したら、次はAPIが何をサポートしているかを確認します。APIのインデックスには、サポートされているAPIの拡張機能を含むnamespacesの項目が公開されています。

WordPress のバージョン 4.4 から 4.6 を使用しているサイトでは、基本的な API インフラストラクチャのみが利用可能であり、エンドポイントを含む完全な API は利用できません。これには oEmbed エンドポイントも含まれます。

{
    "name": "Example WordPress Site",
    "namespaces": [
        "oembed/1.0/"
    ]
}

フルのAPIの機能が利用可能なサイト(つまりWordPress 4.7+またはREST APIプラグインがインストールされているサイト)では、namespacesにもwp/v2の項目があります。

{
    "name": "Example WordPress Site",
    "namespaces": [
        "wp/v2",
        "oembed/1.0/"
    ]
}

コアエンドポイントのいずれかを使おうとする前に、必ず wp/v2 のサポートを確認して API がサポートされているかどうかを確認する必要があります。WordPress 4.4では、すべてのサイトでAPIインフラが有効になりましたが、wp/v2ではコアエンドポイントは含まれていませんでした。WordPress 4.7ではコアエンドポイントが追加されました。

この同じメカニズムは、REST API をサポートする任意のプラグインのサポートを検出するために使用することができます。例えば、以下のルートを登録するプラグインを考えてみましょう。

<?php
register_rest_route( 'testplugin/v1', '/testroute', array( /* ... */ ) );

これは testplugin/v1 ネームスペースをインデックスに追加します。

{
    "name": "Example WordPress Site",
    "namespaces": [
        "wp/v2",
        "oembed/1.0/",
        "testplugin/v1"
    ]
}