はじめに

HTTPはHypertext Transfer Protocolの略で、インターネット全体の基盤となる通信プロトコルです。これがHTTPに初めて触れる経験であっても、あなたが理解している以上のことを知っている可能性があります。最も基本的なレベルでは、HTTPは次のように機能します:

  • 「こんにちはサーバーXYZ、abc.htmlファイルをいただけますか?」
  • 「こんにちは小さなクライアント、もちろん、こちらです」

PHPでHTTPリクエストを送信するためのさまざまな方法があります。WordPress HTTP APIの目的は、可能な限り多くの方法をサポートし、特定のリクエストに最も適した方法を使用することです。

WordPress HTTP APIは、Twitter APIやGoogle Maps APIなど、他のAPIと通信し、相互作用するためにも使用できます。

HTTPメソッド

HTTPには、特定の種類のアクションを説明するいくつかのメソッド、または動詞があります。いくつかのメソッドが存在しますが、WordPressには最も一般的な3つのメソッドに対する事前構築された関数があります。HTTPリクエストが行われるとき、メソッドも一緒に渡され、サーバーがクライアントが要求しているアクションの種類を判断するのに役立ちます。

GET

GETはデータを取得するために使用されます。これは最も一般的に使用される動詞です。ウェブサイトを表示したり、APIからデータを取得したりするたびに、GETリクエストの結果を見ています。実際、あなたのブラウザは、あなたがこの文章を読んでいるサーバーにGETリクエストを送り、この特定の記事を構築するために使用されたデータを要求しました。

POST

POSTは、サーバーにデータを送信し、サーバーが何らかの方法で処理するために使用されます。例えば、連絡フォームです。フォームフィールドにデータを入力し、送信ボタンをクリックすると、ブラウザはデータを取り込み、フォームに入力したテキストを含むPOSTリクエストをサーバーに送信します。そこから、サーバーは連絡リクエストを処理します。

HEAD

HEADは他の2つのメソッドよりもあまり知られていません。HEADは基本的にGETリクエストと同じですが、データを取得するのではなく、データに関する情報のみを取得します。このデータは、データが最後に更新された時期、クライアントがデータをキャッシュすべきかどうか、データのタイプなどを説明します。現代のブラウザは、以前に訪れたページにHEADリクエストを送信して、更新があるかどうかを判断します。更新がない場合、同じコピーを無駄に帯域幅を使用して引き込むのではなく、以前にダウンロードしたページのコピーを見ている可能性があります。

すべての良いAPIクライアントは、GETリクエストを実行する前にHEADを利用して、帯域幅を節約します。HEADが新しいデータがあると言った場合、2つの別々のHTTPリクエストが必要になりますが、GETリクエストのデータサイズは非常に大きくなる可能性があります。HEADがデータが新しいか、キャッシュすべきでないと言った場合にのみGETを使用することで、高価な帯域幅と読み込み時間を節約できます。

カスタムメソッド

PUT、DELETE、TRACE、CONNECTなどの他のHTTPメソッドもあります。これらのメソッドは、WordPressで利用するための事前構築されたメソッドがないため、この記事では取り上げません。また、APIがそれらを実装することはまだ一般的ではありません。

サーバーの設定によっては、自分自身の追加のHTTPメソッドを実装することもできます。標準メソッドの外に出ることは常にリスクがあり、他の開発者があなたのサイトやAPIを利用するクライアントを作成する際に大きな制限を課す可能性がありますが、WordPressでは希望するメソッドを利用することが可能です。この記事では、その方法について簡単に触れます。

レスポンスコード

HTTPは数値と文字列のレスポンスコードの両方を利用します。それぞれの詳細な説明に入るのではなく、標準のレスポンスコードを以下に示します。APIを作成する際に独自のレスポンスコードを定義することができますが、特定の種類のレスポンスをサポートする必要がない限り、標準コードに従うのが最良かもしれません。カスタムコードは通常1xx範囲にあります。

コードクラス

レスポンスの種類は、3桁のコードの最左の数字で迅速に確認できます。

ステータスコード 説明
2xx リクエストは成功しました
3xx リクエストは別のURLにリダイレクトされました
4xx リクエストはクライアントエラーのために失敗しました。通常は無効な認証またはデータの欠如によるものです
5xx リクエストはサーバーエラーのために失敗しました。一般的には欠落または誤設定された設定ファイルによるものです

一般的なコード

これらは、あなたが遭遇する最も一般的なコードです。


| ステータスコード | 説明 |
| —- | —- |
| 200 | OK – リクエストは成功しました |
| 301 | リソースは永久に移動しました |
| 302 | リソースは一時的に移動しました |
| 403 | 禁止 – 通常は無効な認証によるものです |
| 404 | リソースが見つかりません |
| 500 | 内部サーバーエラー |
| 503 | サービスが利用できません |

APIからデータを取得する

GitHubは、多くの公開側面に対してアプリ登録を必要としない優れたAPIを提供しているため、これらのメソッドのいくつかを示すために、例はGitHub APIを対象とします。

WordPressでは、データを取得するのが非常に簡単です。wp_remote_get()関数を使用します。この関数は、次の2つの引数を取ります:

  • 1. $url – データを取得するリソース。これは標準のHTTP形式である必要があります
  • 2. $args – オプション – 挙動やヘッダー(クッキー、リダイレクトの追跡など)を変更するために、ここに引数の配列を渡すことができます。

以下のデフォルトが仮定されますが、$argsパラメータを介して変更できます:

  • method – GET
  • timeout – 5 – 諦めるまでの待機時間
  • redirection – 5 – リダイレクトを追跡する回数。
  • httpversion – 1.0
  • blocking – true – この操作が完了するまでページの残りの部分が読み込みを待つべきか?
  • headers – array()
  • body – null
  • cookies – array()

GitHubユーザーアカウントのURLを使用して、どのような情報を取得できるか見てみましょう

  1. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );

$responseには、リクエストに関するすべてのヘッダー、コンテンツ、およびその他のメタデータが含まれます

  1. Array(
  2. [headers] => Array(
  3. [server] => nginx
  4. [date] => Fri, 05 Oct 2012 04:43:50 GMT
  5. [content-type] => application/json; charset=utf-8
  6. [connection] => close
  7. [status] => 200 OK
  8. [vary] => Accept
  9. [x-ratelimit-remaining] => 4988
  10. [content-length] => 594
  11. [last-modified] => Fri, 05 Oct 2012 04:39:58 GMT
  12. [etag] => "5d5e6f7a09462d6a2b473fb616a26d2a"
  13. [x-github-media-type] => github.beta
  14. [cache-control] => public, s-maxage=60, max-age=60
  15. [x-content-type-options] => nosniff
  16. [x-ratelimit-limit] => 5000
  17. )
  18. [body] => {"type":"User","login":"blobaugh","gravatar_id":"f25f324a47a1efdf7a745e0b2e3c878f","public_gists":1,"followers":22,"created_at":"2011-05-23T21:38:50Z","public_repos":31,"email":"[email protected]","hireable":true,"blog":"http://ben.lobaugh.net","bio":null,"following":30,"name":"Ben Lobaugh","company":null,"avatar_url":"https://secure.gravatar.com/avatar/f25f324a47a1efdf7a745e0b2e3c878f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","id":806179,"html_url":"https://github.com/blobaugh","location":null,"url":"https://api.github.com/users/blobaugh"}
  19. [response] => Array(
  20. [preserved_text 5237511b45884ac6db1ff9d7e407f225 /] => 200
  21. [message] => OK
  22. )
  23. [cookies] => Array()
  24. [filename] =>
  25. )

同じヘルパー関数は、前の2つの関数と同様にこの関数でも使用できます。ここでの例外は、HEADは常にボディを返さないため、その要素は常に空になります。

常に欲しかったボディを取得する

ボディだけを取得するには、wp_remote_retrieve_body()を使用します。この関数は、他のwp_remote_X関数からのレスポンスを1つのパラメータとして取ります。取得するのが次の値でない場合です。

  1. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
  2. $body = wp_remote_retrieve_body( $response );

前の例のGitHubリソースを使用すると、$bodyは

  1. {"type":"User","login":"blobaugh","public_repos":31,"gravatar_id":"f25f324a47a1efdf7a745e0b2e3c878f","followers":22,"avatar_url":"https://secure.gravatar.com/avatar/f25f324a47a1efdf7a745e0b2e3c878f?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png","public_gists":1,"created_at":"2011-05-23T21:38:50Z","email":"[email protected]","following":30,"name":"Ben Lobaugh","company":null,"hireable":true,"id":806179,"html_url":"https://github.com/blobaugh","blog":"http://ben.lobaugh.net","location":null,"bio":null,"url":"https://api.github.com/users/blobaugh"}

レスポンスからボディを取得する以外に他の操作を行う必要がない場合、コードを1行に減らすことができます

  1. $body = wp_remote_retrieve_body( wp_remote_get( 'https://api.github.com/users/blobaugh' ) );

これらのヘルパー関数の多くは、同様に1行で使用できます。

レスポンスコードを取得する

取得が成功したことを確認するために、レスポンスコードを確認したい場合があります。これはwp_remote_retrieve_response_code()関数を介して行うことができます:

  1. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
  2. $http_code = wp_remote_retrieve_response_code( $response );

成功した場合、$http_codeには200が含まれます。

特定のヘッダーを取得する

特定のヘッダー、例えばlast-modifiedを取得したい場合、wp_remote_retrieve_header()を使用して行うことができます。この関数は2つのパラメータを取ります

  • 1. $response – get呼び出しからのレスポンス
  • 2. $header – 取得するヘッダーの名前

last-modifiedヘッダーを取得するには

  1. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
  2. $last_modified = wp_remote_retrieve_header( $response, 'last-modified' );

$last_modifiedには[last-modified] => Fri, 05 Oct 2012 04:39:58 GMTが含まれます

wp_remote_retrieve_headers( $response )を使用して、すべてのヘッダーを配列で取得することもできます。

基本認証を使用してGETする

より安全なAPIは、さまざまな認証タイプの1つ以上を提供します。一般的な、ただしあまり安全ではない認証方法はHTTP Basic Authenticationです。これは、wp_remote_get()関数の2番目のパラメータに「Authorization」を渡すことでWordPressで使用できます。他のHTTPメソッド関数でも同様です。

  1. $args = array(
  2. 'headers' => array(
  3. 'Authorization' => 'Basic ' . base64_encode( YOUR_USERNAME . ':' . YOUR_PASSWORD )
  4. )
  5. );
  6. wp_remote_get( $url, $args );

APIにデータをPOSTする

同じヘルパーメソッド(wp_remote_retrieve_body()など)は、すべてのHTTPメソッド呼び出しに利用可能で、同じ方法で使用されます。

データをPOSTするには、wp_remote_post()関数を使用し、wp_remote_get()とまったく同じパラメータを取ります。ここで注意すべきは、2番目のパラメータの配列内のすべての要素を渡す必要があることです。Codexはデフォルトの受け入れ可能な値を提供します。今は送信するデータにのみ気を配ればよく、他の値はデフォルトに設定されます。

サーバーにデータを送信するには、データの連想配列を構築する必要があります。このデータは'body'値に割り当てられます。サーバー側では、その値は$_POST変数に表示されることになります。つまり、body => array( 'myvar' => 5 )がサーバー上で$_POST['myvar'] = 5の場合です。

GitHubは前の例で使用したAPIにPOSTすることを許可していないため、この例ではそれを許可していると仮定します。通常、APIにデータをPOSTしたい場合は、APIの管理者に連絡してAPIキーまたは他の認証トークンを取得する必要があります。これは、あなたのアプリケーションがAPI上のデータを操作することが許可されていることを証明するもので、ユーザーとしてウェブサイトにログインするのと同じです。

次のフィールドを持つ連絡フォームを送信すると仮定しましょう:名前、メール、件名、コメント。ボディを設定するには、次のようにします:

  1. $body = array(
  2. 'name' => 'Jane Smith',
  3. 'email' => '[email protected]',
  4. 'subject' => 'Checkout this API stuff',
  5. 'comment' => 'I just read a great tutorial. You gotta check it out!',
  6. );

次に、wp_remote_post()の2番目のパラメータに渡される他の値を設定する必要があります

  1. $args = array(
  2. 'body' => $body,
  3. 'timeout' => '5',
  4. 'redirection' => '5',
  5. 'httpversion' => '1.0',
  6. 'blocking' => true,
  7. 'headers' => array(),
  8. 'cookies' => array(),
  9. );

そしてもちろん、呼び出しを行うために

  1. $response = wp_remote_post( 'http://your-contact-form.com', $args );

帯域幅使用を抑えるためのHEAD

リソースの状態を確認するためにHEADを使用して取得する前に確認することは非常に重要であり、時にはAPIによって要求されることもあります。トラフィックの多いAPIでは、GETは通常、1分または1時間あたりのリクエスト数に制限されます。HEADリクエストがAPIのデータが更新されたことを示さない限り、GETリクエストを試みる必要はありません。

前述のように、HEADにはデータが更新されたかどうか、データをキャッシュすべきか、キャッシュコピーの有効期限、時にはAPIへのリクエストのレート制限に関するデータが含まれています。

GitHubの例に戻ると、注意すべきいくつかのヘッダーがあります。これらのヘッダーのほとんどは標準ですが、APIのドキュメントを常に確認して、どのヘッダーが何と呼ばれているか、そしてその目的を理解することが重要です。

  • x-ratelimit-limit – 一定期間内に許可されるリクエストの数
  • x-ratelimit-remaining – 一定期間内に残りの利用可能なリクエストの数
  • content-length – コンテンツのサイズ(バイト単位)。コンテンツがかなり大きい場合にユーザーに警告するのに役立ちます
  • last-modified – リソースが最後に変更された時期。キャッシングツールに非常に役立ちます
  • cache-control – クライアントがキャッシングをどのように処理すべきか

次のコードは、私のGitHubユーザーアカウントのHEAD値を確認します:

  1. $response = wp_remote_head( 'https://api.github.com/users/blobaugh' );

$responseは次のようになります

  1. Array(
  2. [headers] => Array
  3. (
  4. [server] => nginx
  5. [date] => Fri, 05 Oct 2012 05:21:26 GMT
  6. [content-type] => application/json; charset=utf-8
  7. [connection] => close
  8. [status] => 200 OK
  9. [vary] => Accept
  10. [x-ratelimit-remaining] => 4982
  11. [content-length] => 594
  12. [last-modified] => Fri, 05 Oct 2012 04:39:58 GMT
  13. [etag] => "5d5e6f7a09462d6a2b473fb616a26d2a"
  14. [x-github-media-type] => github.beta
  15. [cache-control] => public, s-maxage=60, max-age=60
  16. [x-content-type-options] => nosniff
  17. [x-ratelimit-limit] => 5000
  18. )
  19. [body] =>
  20. [response] => Array
  21. (
  22. [preserved_text 39a8515bd2dce2aa06ee8a2a6656b1de /] => 200
  23. [message] => OK
  24. )
  25. [cookies] => Array(
  26. )
  27. [filename] =>
  28. )

すべての同じヘルパー関数は、前の2つの関数と同様にこの関数でも使用できます。ここでの例外は、HEADは常にボディを返さないため、その要素は常に空になります。

あらゆるリクエストを行う

上記の関数のいずれかでサポートされていないHTTPメソッドを使用してリクエストを行う必要がある場合は、パニックにならないでください。WordPressを開発している素晴らしい人々はすでにそれを考慮しており、wp_remote_request()を提供しています。この関数はwp_remote_get()と同じ2つのパラメータを取り、HTTPメソッドを指定することもできます。渡す必要があるデータは、あなたのメソッド次第です。

DELETEメソッドの例を送信するには、次のようなものが必要です:

  1. $args = array(
  2. 'method' => 'DELETE',
  3. );
  4. $response = wp_remote_request( 'http://some-api.com/object/to/delete', $args );

キャッシングの紹介

キャッシングは、一般的に使用されるオブジェクトや構築にかなりの時間を要するオブジェクトを、高速オブジェクトストアに保存し、後のリクエストで迅速に取得できるようにする実践です。これにより、オブジェクトを再度取得して構築するための時間を費やす必要がなくなります。キャッシングは、ウェブサイトの最適化の一部であり、単独で一連の記事に入ることができる広範な主題です。以下は、キャッシングの紹介とAPIレスポンスのためのキャッシュを迅速に設定するためのシンプルで効果的な方法です。

なぜAPIレスポンスをキャッシュすべきなのでしょうか?それは、外部APIがあなたのサイトを遅くするからです。多くのコンサルタントは、外部APIにアクセスすることで、接続数と処理を減らし、コストのかかる帯域幅を削減することでウェブサイトのパフォーマンスが向上すると言いますが、時にはこれは単に真実ではありません。

サーバーがデータを送信できる速度と、リモートサーバーがリクエストを処理し、データを構築し、返送するのにかかる時間との間には微妙なバランスがあります。もう一つの明白な側面は、多くのAPIが一定期間内にリクエストの数を制限しており、アプリケーションが同時に接続できる数にも制限がある可能性があることです。キャッシングは、データのコピーをサーバーに置くことでこれらのジレンマを解決するのに役立ちます。

いつキャッシュすべきか?

この質問に対する即答は常にですが、やはりキャッシュすべきでない場合もあります。リアルタイムデータを扱っている場合や、APIがヘッダーでキャッシュしないように明示的に指示している場合は、キャッシュしない方が良いかもしれませんが、他のすべての状況では、APIから取得したリソースをキャッシュするのは一般的に良いアイデアです。

WordPressトランジエント

WordPressトランジエントは、キャッシュされたオブジェクトを保存して使用する便利な方法を提供します。トランジエントは指定された時間だけ存在し、APIからのリソースが更新されると期限切れになります。WordPressのトランジエント機能を使用することは、あなたが出会う中で最も簡単なキャッシングシステムかもしれません。すべての重い作業を行うための関数は3つだけです。

オブジェクトをキャッシュする(トランジエントを設定する)

オブジェクトをキャッシュするには、set_transient()関数を使用します。この関数は次の3つのパラメータを取ります:

  • 1. $transient – 将来の参照のためのトランジエントの名前
  • 2. $value – トランジエントの値
  • 3. $expiration – トランジエントを保存してから期限切れになるまでの秒数

上記のGitHubユーザー情報レスポンスを1時間キャッシュする例は次のとおりです:

  1. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
  2. set_transient( 'prefix_github_userinfo', $response, 60 * 60 );

キャッシュされたオブジェクトを取得する(トランジエントを取得する)

キャッシュされたオブジェクトを取得するのは、トランジエントを設定するよりもかなり複雑です。トランジエントをリクエストする必要がありますが、その後、そのトランジエントが期限切れかどうかを確認し、期限切れの場合は更新されたデータを取得する必要があります。通常、set_transient()呼び出しはget_transient()呼び出しの内部で行われます。以下は、GitHubユーザープロファイルのトランジエントデータを取得する例です:

  1. $github_userinfo = get_transient( 'prefix_github_userinfo' );
  2. if ( false === $github_userinfo ) {
  3. // Transient expired, refresh the data
  4. $response = wp_remote_get( 'https://api.github.com/users/blobaugh' );
  5. set_transient( 'prefix_github_userinfo', $response, HOUR_IN_SECONDS );
  6. }
  7. // Use $github_userinfo as you will

キャッシュされたオブジェクトを削除する(トランジエントを削除する)

キャッシュされたオブジェクトを削除するのは、すべてのトランジエント関数の中で最も簡単です。トランジエントの名前のパラメータを渡すだけで完了です。

GitHubユーザー情報を削除するには:

  1. delete_transient( 'blobaugh_github_userinfo' );

トランジエントに関する詳細情報はこちらで確認できます。