1. ホーム
  2. web-services

[解決済み] RESTを理解する。動詞、エラーコード、認証

2022-03-16 14:33:45

質問

PHPベースのWebアプリケーション、データベース、CMSにおいて、APIをデフォルト関数にラップする方法を探しています。

いろいろと調べてみたところ、いくつかのフレームワークが見つかりました。私の質問の答えに加え、以下のものがあります。 トニック は、非常に軽量で気に入っているRESTフレームワークです。

RESTはシンプルなところが一番好きで、これをベースにAPIアーキテクチャを作りたいと思っています。基本的な原理を理解しようとしているのですが、まだ完全に理解できていません。そのため、いろいろと質問があります。

1. 私の理解は正しいですか?

例えば、リソース "users" があるとします。私はこのようにいくつものURIを設定することができます。

/api/users     when called with GET, lists users
/api/users     when called with POST, creates user record
/api/users/1   when called with GET, shows user record
               when called with PUT, updates user record
               when called with DELETE, deletes user record

は、これまでのRESTfulアーキテクチャの表現として正しいでしょうか?

2. 動詞を増やしたい

理論的にはCreate, Update, Deleteで十分かもしれませんが、実際にはもっと多くの動詞が必要になるでしょう。これらは 可能性がある しかし、これらは特定の戻りコードを持つことができる特定のアクションであり、私はそれらをすべて1つのアクションに投げ入れたくありません。

ユーザーの例で思い浮かぶのは、以下のようなものです。

activate_login
deactivate_login
change_password
add_credit

のようなアクションを、RESTfulなURLアーキテクチャでどのように表現すればよいのでしょうか?

私の直感では、次のようなURLへのGETコールを行うことになるでしょう。

/api/users/1/activate_login 

を実行し、ステータスコードの返事を期待する。

HTTPの動詞を使うという考え方から外れてしまいますが。どうでしょう?

3. エラーメッセージとコードの返し方

RESTの美しさの大部分は、標準的なHTTPメソッドを使用することに起因しています。エラー時には、3xx、4xx、5xxのエラーステータスコードを持つヘッダを出力します。エラーの詳細な説明については、ボディを使用することができます(分かりますか?) ここまではいいんだけど。しかし 独自のエラーコード 何が問題だったのかをより詳しく説明するもの(例えば、"failed to connect to database" や "database login wrong" など)でしょうか?メッセージと一緒にボディに入れると、後で解析しなければなりません。このような場合の標準的なヘッダーはあるのでしょうか?

4. 認証の方法

  • RESTの原則に従ったAPIキーベースの認証はどのようなものでしょうか?
  • RESTクライアントを認証する際にセッションを使用することに対して、RESTの原則のあからさまな違反であるということ以外に、何か有力なポイントはありますか? :) (半分冗談です。セッションベースの認証は、私の既存のインフラストラクチャとうまく機能します。)

解決方法は?

この質問に気づいたのが2日ほど遅かったのですが、いくつかの洞察を加えることができると感じています。あなたのRESTfulベンチャーに役立つことを願っています。


ポイント1:私の理解は正しいか?

正しく理解されましたね。これはRESTfulアーキテクチャの正しい表現です。次のようなマトリックスがあります。 ウィキペディア 名詞と動詞を定義するのに非常に便利です。


を扱う場合 コレクション のようなURI。 http://example.com/resources/

  • GET : コレクションのメンバーをリストアップし、さらにナビゲートするためのメンバーURIを完備。例えば、販売されているすべての車をリストアップします。

  • プット : 意味は "コレクション全体を別のコレクションに置き換える" と定義されています。

  • POST : ID がコレクションによって自動的に割り当てられる、新しいエントリを作成します。作成されたIDは、通常この操作によって返されるデータの一部として含まれます。

  • DELETE : コレクション全体を削除する」という意味です。


を扱う場合 メンバー のようなURI。 http://example.com/resources/7HOU57Y

  • GET : 適切な MIME タイプで表現された、コレクションのアドレス指定されたメンバーの表現を取得する。

  • プット : コレクションの指定されたメンバーを更新するか、指定されたIDでメンバーを作成します。

  • POST : 指定されたメンバーをそれ自体のコレクションとして扱い、その新しい下位を作成します。

  • DELETE : コレクションから指定されたメンバーを削除します。


ポイント2:動詞を増やしたい

一般に、動詞が足りないと思うときは、実はリソースを再認識する必要があるのかもしれません。RESTでは、常にリソース、またはリソースの集合体に対して動作していることを忘れないでください。何をリソースとして選択するかは、API定義にとって非常に重要である。

ログインの有効化/無効化 : 新しいセッションを作成する場合、"the session" をリソースとして考慮するとよいでしょう。新しいセッションを作成するには、POSTで http://example.com/sessions/ を、本文にクレデンシャルを記述してください。期限切れにするには、PUT または DELETE (セッションの履歴を残すかどうかによる) で http://example.com/sessions/SESSION_ID .

パスワードを変更する。 今回は、リソースが「ユーザー」です。へのPUTが必要でしょう。 http://example.com/users/USER_ID で、本文に古いパスワードと新しいパスワードを記述します。あなたは "the user" リソースに対して行動しており、パスワードの変更は単に更新要求です。これは、リレーショナル・データベースにおけるUPDATE文に非常によく似ています。

<ブロッククオート

私の直感では、GETコールで のようなURLに /api/users/1/activate_login

これは、RESTの基本原則である「HTTP動詞の正しい使い方」に反しています。GETリクエストは、いかなる副作用も残してはいけません。

例えば、GETリクエストはデータベース上にセッションを作成したり、新しいセッションIDを持つクッキーを返したり、サーバー上にいかなる残滓も残してはいけません。GET動詞は、データベースエンジンのSELECT文のようなものです。GET動詞を使ったリクエストに対するレスポンスは、静的なWebページをリクエストしたときと同じように、同じパラメータでリクエストしたときにキャッシュ可能であるべきであることを覚えておいてください。


ポイント3:エラーメッセージやコードを返す方法

4xxや5xxのHTTPステータスコードは、エラーのカテゴリーとして考えてください。ボディにエラーの内容を詳しく記述することができます。

データベースへの接続に失敗しました。 / データベースへの不正なログイン : 一般に、この種のエラーには500エラーを使用すべきです。これはサーバー側のエラーです。クライアントは何も間違っていません。500エラーは通常、quot;retryable"と見なされます。つまり、クライアントはまったく同じリクエストを再試行でき、サーバーのトラブルが解決すれば成功すると予想されます。ボディに詳細を記述することで、クライアントが我々人間にコンテキストを提供できるようになります。

もうひとつのエラーのカテゴリーは、4xxファミリーで、一般にクライアントが何か間違ったことをしたことを示します。特に、このカテゴリのエラーは通常、リクエストは永久に失敗し続けるので、 そのままでは再試行する必要がないことをクライアントに示す。つまり、クライアント はこのリクエストを再試行する前に何かを変更する必要がある。例えば、"Resource not found" (HTTP 404) や "Malformed Request" (HTTP 400) エラーはこのカテゴリに分類されるでしょう。


ポイント4:認証の方法

ポイント1で指摘したように、ユーザーを認証する代わりに、セッションを作成することを考えた方がよいでしょう。新しい "Session ID" と適切な HTTP ステータスコード (200: Access Granted または 403: Access Denied) が返されます。

次に、RESTful サーバーに次のように尋ねます: "このセッション ID のリソースを GET してもらえますか?

RESTはステートレス(状態なし)なので、認証モードはありません。あなたはセッションを作成し、このセッション ID をパラメータとしてリソースを与えるようサーバに要求し、ログアウト時にセッションを削除するか失効させます。