RESTについて:動詞、エラーコード、認証


602

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

私は周りを見回して、いくつかの「スケルトン」フレームワークを見つけました。私の質問の回答に加えて、非常に軽量であることから気に入っているRESTフレームワークであるTonicがあります。

RESTはそのシンプルさから最も気に入っており、それに基づいてAPIアーキテクチャを作成したいと考えています。私は基本原則を理解しようとしていますが、まだ完全には理解していません。したがって、いくつかの質問。

1.私はそれを正しく理解していますか?

「ユーザー」というリソースがあるとします。私は次のようにいくつかの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.動詞がもっと必要

理論的には作成、更新、削除で十分かもしれませんが、実際にはもっと多くの動詞が必要になります。これらは更新リクエストに埋め込むことできるものであることに気づきましたが、これらは特定の戻りコードを持つ特定のアクションであり、それらすべてを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エラーステータスコードのヘッダーを出力します。エラーの詳細な説明については、本文を使用できます(右?)。ここまでは順調ですね。しかし、何が悪かったか(たとえば、「データベースへの接続に失敗した」、または「データベースログインが間違っている」など)を説明する詳細な独自のエラーコードを送信する方法は何でしょうか。メッセージと一緒に本文に入れた場合は、後で解析する必要があります。この種の標準ヘッダーはありますか?

4.認証を行う方法

  • REST原則に従うAPIキーベースの認証はどのようになりますか?
  • RESTの原則の露骨な違反であるということ以外に、RESTクライアントを認証するときにセッションを使用することに強い点はありますか?:)(ここでは冗談ですが、セッションベースの認証は私の既存のインフラストラクチャでうまく機能します。)

13
@ダニエル、編集ありがとうございます。"I more verbs"は意図的なしゃれでしたが、そのままにしておきます。読みやすくなりました。:)
Pekka

1
ところで、エラーの説明について。応答のヘッダーにエラーの説明を入れてしまいました。「エラーの説明」という名前のヘッダーを追加するだけです。
Andrii Muzychuk 2015年

これは、アプリケーションのセキュリティの質問に似ています。アプリケーションのセキュリティはRESTの目的ではありません。
Nazar Merza

@NazarMerza 1.、2、3。アプリケーションのセキュリティの質問はどうですか?
Pekka

回答:


621

この質問に数日遅れて気づきましたが、少し洞察を深めることができると思います。これがRESTfulベンチャーに役立つことを願っています。


ポイント1:私はそれを正しく理解していますか?

あなたは正しく理解しました。これはRESTfulアーキテクチャの正しい表現です。名詞と動詞を定義するには、Wikipediaの次のマトリックスが非常に役立つことがあります。


次のようなコレクション URI を処理する場合:http://example.com/resources/

  • GET:コレクションのメンバーを一覧表示し、さらに移動するためのメンバーURIを入力します。たとえば、販売中のすべての車をリストします。

  • PUT:「コレクション全体を別のコレクションに置き換える」と定義されている意味。

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

  • DELETE:「コレクション全体を削除する」と定義された意味。


次のようなメンバー URI を処理する場合:http://example.com/resources/7HOU57Y

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

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

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

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


ポイント2:動詞がもっと必要

一般に、より多くの動詞が必要だと思う場合、それは実際にはリソースを再特定する必要があることを意味します。RESTでは、常にリソースまたはリソースのコレクションを操作することに注意してください。リソースとして何を選択するかは、API定義にとって非常に重要です。

ログインのアクティブ化/非アクティブ化:新しいセッションを作成する場合は、「セッション」をリソースと見なすことができます。新しいセッションを作成するには、POSTを使用http://example.com/sessions/して本文に資格情報を含めます。それを期限切れにするには、PUTまたはDELETEを使用します(セッション履歴を保持するかどうかによって異なります)http://example.com/sessions/SESSION_ID

パスワードの変更:今回はリソースは「ユーザー」です。http://example.com/users/USER_ID本文の新旧のパスワードをPUTする必要があります。あなたは「ユーザー」リソースを操作しており、パスワードの変更は単に更新リクエストです。これは、リレーショナルデータベースのUPDATEステートメントによく似ています。

私の本能は、次のようなURLに対してGET呼び出しを行うことです /api/users/1/activate_login

これは、非常に中心的なRESTの原則に反します。HTTP動詞の正しい使用法です。GET要求は、副作用を残してはなりません。

たとえば、GETリクエストでは、データベース上にセッションを作成したり、新しいセッションIDでCookieを返したり、サーバーに残したりしないでください。GET動詞は、データベースエンジンのSELECTステートメントに似ています。静的なWebページを要求するときと同じように、GET動詞を使用した要求への応答は、同じパラメーターで要求されたときにキャッシュ可能でなければならないことに注意してください。


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

4xxまたは5xx HTTPステータスコードをエラーカテゴリと見なします。本体の誤差を詳しく説明できます。

データベースへの接続に失敗しました: / 不正なデータベースログイン:一般に、これらのタイプのエラーには500エラーを使用する必要があります。これはサーバー側のエラーです。クライアントは何も悪いことをしませんでした。500エラーは通常「再試行可能」と見なされます。つまり、クライアントは、まったく同じ要求を再試行し、サーバーの問題が解決されると成功することを期待できます。ボディに詳細を指定して、クライアントが人間に何らかのコンテキストを提供できるようにします。

エラーのもう1つのカテゴリは、4xxファミリです。これは一般に、クライアントが何か間違ったことを示しています。特に、このカテゴリのエラーは通常、リクエストが永続的に失敗し続けるため、リクエストをそのまま再試行する必要がないことをクライアントに示します。つまり、クライアントはこのリクエストを再試行する前に何かを変更する必要があります。たとえば、「リソースが見つかりません」(HTTP 404)または「不正なリクエスト」(HTTP 400)エラーはこのカテゴリに分類されます。


ポイント4:認証の方法

ポイント1で指摘したように、ユーザーを認証する代わりに、セッションの作成を検討する必要がある場合があります。新しい「セッションID」と適切なHTTPステータスコード(200:アクセス許可または403:アクセス拒否)が返されます。

次に、RESTfulサーバーに「このセッションIDのリソースを取得できますか?」と質問します。

認証モードはありません-RESTはステートレスです。セッションを作成し、このセッションIDをパラメーターとして使用してリソースを提供するようサーバーに要求し、ログアウト時にセッションをドロップまたは期限切れにします。


6
非常に良いですが、を使用PUTしてパスワードを変更することはおそらく間違っています。PUTリソース全体が必要なので、HTTP(したがってHATEOAS REST)に準拠するには、すべてのユーザー属性を送信する必要があります。むしろ、単にパスワードを変更するには、PATCHまたはを使用する必要がありPOSTます。
Lawrence Dol 2014年

1
この投稿は、「POST:アドレス指定されたメンバーをそれ自体のコレクションとして扱い、その新しい従属を作成する」ことについてさらに詳しく説明した場合に最適だと思います。手段。-グーグルでそれが何を意味するのかを見つけました-それはあなたのそうでなければ素晴らしい答えの例外です。
Martin Konecny 14

6
最後の文には同意しません。RESTがステートレスであることを説明しています。ログインしてセッションを作成し、ログアウトして何らかの作業を行った後にセッションを終了することが、ステートフルAPIの最良の例です。
ブランドン

1
「これは、非常に中心的なREST原則に反します。HTTP動詞の正しい使用法です。GET要求は、副作用を残してはなりません。」-リソースのヒット数を維持したい場合はどうなりますか?
bobbyalex

1
この記事はあなたの質問に答えるべきです。saipraveenblog.wordpress.com/2014/09/29/rest-api-best-practices
java_geek

79

簡単に言えば、あなたはこれを完全に逆に行っています。

使用する必要があるURLからこれに近づいてはいけません。システムに必要なリソースと、それらのリソースをどのように表すか、およびリソースとアプリケーションの状態との間の相互作用を決定すると、URLは事実上「無料」で提供されます。

ロイ・フィールディングを引用するには

REST APIは、リソースの表現とアプリケーションの状態の駆動に使用されるメディアタイプの定義、または既存の標準メディアタイプの拡張リレーション名やハイパーテキスト対応マークアップの定義に、そのほとんどすべての記述的努力を費やすべきです。どのURIでどのメソッドを使用するかを説明するために費やした労力は、メディアタイプの処理ルールのスコープ内で完全に定義する必要があります(ほとんどの場合、既存のメディアタイプによってすでに定義されています)。[ここでの失敗は、帯域外情報がハイパーテキストではなく対話を促進していることを意味します。]

人々は常にURIから始まり、これが解決策であると考えます。特に、上で引用したように、RESTアーキテクチャの主要な概念を見落とす傾向があります。 」

正直に言うと、多くの人が一連のURIといくつかのGET、PUT、POSTを見て、RESTは簡単だと考えています。RESTは簡単ではありません。RPC over HTTPは簡単で、HTTPペイロードを介してプロキシされたデータのブロブを前後に移動することは簡単です。ただし、RESTはそれだけではありません。RESTはプロトコルに依存しません。HTTPは非常に人気があり、RESTシステムに適しています。

RESTは、メディアタイプとその定義に含まれ、アプリケーションがハイパーテキスト(リンク、効果的に)を介してこれらのリソースで利用可能なアクションをどのように実行するかを示します。

RESTシステムには、メディアタイプについてさまざまな見方があります。アプリケーション固有のペイロードを優先するものもあれば、既存のメディアタイプをアプリケーションに適したロールに引き上げるのを好むものもあります。たとえば、一方では、マイクロフォーマットやその他のメカニズムを通じて、XHTMLのようなものを表現として使用するのではなく、アプリケーションに合わせて設計された特定のXMLスキーマがあるとします。

XHTMLは人間が駆動するWebと機械が駆動するWebの両方に重なるシナリオで非常にうまく機能していると思いますが、前者のより具体的なデータタイプは、機械間の相互作用を促進するのに適しています。私は、商品フォーマットの高揚がコンテンツの交渉を潜在的に困難にする可能性があることを発見しました。「application / xml + yourresource」は「application / xhtml + xml」よりもメディアタイプとしてより具体的です。後者は、マシンクライアントが実際に関心を持っているものでもそうでないものでも、多くのペイロードに適用できるためです。内省せずに決定します。

ただし、XHTMLは(明らかに)Webブラウザとレンダリングが非常に重要な人間のWebで非常にうまく機能します。

あなたのアプリケーションは、そのような種類の決定を導きます。

RESTシステムを設計するプロセスの一部は、システムの最初のクラスのリソースを発見することです。派生物とともに、プライマリリソースの操作をサポートするために必要なリソースをサポートします。リソースが検出されると、それらのリソースの表現と、次の課題のため、表現内のハイパーテキストを介してリソースフローを示す状態図が表示されます。

ハイパーテキストシステムでのリソースの各表現は、実際のリソース表現とリソースで利用可能な状態遷移の両方を組み合わせていることを思い出してください。各リソースをグラフのノードと見なします。リンクは、そのノードから他の状態に向かう線です。これらのリンクは、クライアントに何ができるかだけでなく、何をするために何が必要かを通知します(適切なリンクは必要なURIとメディアタイプを組み合わせているため)。

たとえば、次のような場合があります。

<link href="http://example.com/users" rel="users" type="application/xml+usercollection"/>
<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>

ドキュメントでは、「users」という名前のrelフィールドと、「application / xml + youruser」のメディアタイプについて説明します。

これらのリンクは冗長に見えるかもしれませんが、ほとんど同じURIと通信しています。しかし、そうではありません。

これは、「ユーザー」関係の場合、そのリンクがユーザーのコレクションについて話しているためであり、統一されたインターフェースを使用してコレクションを操作できます(GETですべてを取得、DELETEですべてを削除するなど)。

このURLにPOSTする場合は、「application / xml + usercollection」ドキュメントを渡す必要があります。このドキュメントには、ドキュメント内に単一のユーザーインスタンスのみが含まれるため、ユーザーを追加できる場合とそうでない場合があります。一度。おそらく、ドキュメントでは、コレクションの代わりに、単一のユーザータイプを渡すだけでよいと提案されています。

「検索」リンクとそのメディアタイプで定義されているように、検索を実行するためにアプリケーションが必要とするものを確認できます。検索メディアタイプのドキュメントには、これがどのように動作するか、および結果として何が期待できるかが記載されています。

ただし、ここで重要なのは、URI自体は基本的に重要ではないということです。アプリケーションは、クライアントではなくURIを制御します。いくつかの「エントリポイント」を超えて、クライアントはアプリケーションが提供するURIに依存する必要があります。

クライアントは、メディアタイプを操作および解釈する方法を知っている必要がありますが、それがどこにあるかを気にする必要はあまりありません。

これらの2つのリンクは、クライアントの観点では意味的に同一です。

<link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/>
<link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/>

したがって、リソースに集中してください。アプリケーションでの状態遷移と、それがどのようにして最良に達成されるかに焦点を当てます。


1
この非常に深い答えをウィルに感謝します。いくつかのポイントを取った。「URLがどう見えるか」からの企画は逆にやっていることに気づき、リソース側からも企画しています。URLを操作するだけで、コンセプトを理解しやすくなります。それは可能性があり、私の要件は、あなたがそれをここで定義するように100%RESTの原則に従わないシステムで満たすことができることになります。各リソースタイプの要件の完全なリストを引き出します。その時点で決定できると思います。乾杯。
Pekka

30

re 1:これまでのところ問題ありません。新しく作成されたユーザーのURIを、POSTへの応答の一部として「Location:」ヘッダーで、「201 Created」ステータスコードとともに返すことを忘れないでください。

再2:GETを介したアクティブ化は悪い考えであり、URIに動詞を含めることはデザインの匂いです。GETでフォームを返すことを検討してください。Webアプリでは、これは送信ボタンを持つHTMLフォームです。APIの使用例では、アカウントをアクティブにするために、PUTにURIを含む表現を返すことができます。もちろん、このURIをPOSTの/ usersへの応答に含めることもできます。PUTを使用すると、リクエストがべき等であることを確認できます。つまり、クライアントが成功したかどうかわからない場合でも、リクエストを安全に再送信できます。一般に、動詞をどのリソースに変換できるかを考えます(「動詞の統一」のようなもの)。特定のアクションが最も密接に連携している方法を自問してください。たとえば、change_password-> PUT; 非アクティブ化->おそらく削除; add_credit->おそらくPOSTまたはPUT。

re 3.グローバルな標準化に値するほど一般的であると思わない限り、新しいステータスコードを作成しないでください。利用可能な最も適切なステータスコードを使用するように頑張ってください(RFC 2616でそれらすべてを読んでください)。応答本文に追加情報を含めます。本当に、本当に新しいステータスコードを作成したい場合は、もう一度考えてください。それでも信じる場合は、少なくとも正しいカテゴリを選択してください(1xx-> OK、2xx->情報、3xx->リダイレクト、4xx->クライアントエラー、5xx->サーバーエラー)。新しいステータスコードを作成するのは悪い考えだと言ったでしょうか。

re 4.可能であれば、HTTPに組み込まれている認証フレームワークを使用します。GoogleがGDataで認証を行う方法を確認してください。一般に、APIキーをURIに含めないでください。セッションを避けてスケーラビリティを高め、キャッシュをサポートするようにしてください。以前に発生したことが原因でリクエストへの応答が異なる場合は、通常、特定のサーバープロセスインスタンスに縛られています。セッション状態をクライアント状態(たとえば、後続の要求の一部にする)にするか、または(サーバー)リソース状態にすることで明示的にする、つまり、独自のURIを与えることをお勧めします。


APIキーをURLに含めない理由を説明できますか?プロキシログに表示されるためですか。キーが一時的で時間ベースの場合はどうなりますか?HTTPSが使用されている場合はどうなりますか?
MikeSchinkel

4
精神に違反すること(URIは物事を識別する必要があります)とは別に、主な結果はキャッシングを台無しにすることです。
Stefan Tilkov、2010

22

1.リソースを設計する方法について正しい考えがあります、IMHO。変わらない。

2. HTTPをより多くの動詞で拡張しようとするのではなく、提案された動詞を基本的なHTTPメソッドとリソースの観点から削減できるものを検討します。たとえば、activate_login動詞の代わりに、次のようなリソースを設定できます。/api/users/1/login/activeこれは単純なブール値です。ログインをアクティブにするにPUTは、「true」または1か何かを示すドキュメントをそこに置きます。非アクティブ化PUTするには、空のドキュメント、または0またはfalseと表示されているドキュメント。

同様に、パスワードを変更または設定するには、s〜を実行PUT/api/users/1/passwordます。

(クレジットのような)何かを追加する必要があるときはいつでも、POSTsの観点から考えてください。たとえば、追加するクレジットの数を含む本文POSTなどのリソースに対してを実行できます/api/users/1/creditsPUT同じリソースのA を使用して、追加ではなく値を上書きすることができます。POST本文に負の数が含まれるA は減算されます。

3.基本的なHTTPステータスコードを拡張しないことを強くお勧めします。状況に正確に一致するものが見つからない場合は、最も近いものを選択して、エラーの詳細を応答の本文に入力します。また、HTTPヘッダーは拡張可能であることを忘れないでください。アプリケーションでは、必要なすべてのカスタムヘッダーを定義できます。たとえば、私が取り組んだ1つのアプリケーションは404 Not Found、複数の状況でを返す可能性があります。クライアントに理由で応答本文を解析させるのではなくX-Status-Extended、独自のステータスコード拡張を含む新しいヘッダーを追加しました。したがって、次のような応答が表示される場合があります。

HTTP/1.1 404 Not Found    
X-Status-Extended: 404.3 More Specific Error Here

このようにして、WebブラウザーのようなHTTPクライアントは通常の404コードの処理方法を認識し、より洗練されたHTTPクライアントはX-Status-Extendedより具体的な情報のヘッダーを選択することができます。

4.認証には、可能であればHTTP認証を使用することをお勧めします。しかし、私にとっては、Cookieベースの認証を使用する方が簡単であれば、何も問題はありません。


4
「拡張」リソースを使用して、より大きなリソースの小さな部分に物事を行うというきちんとしたアイデア。
ウォンブル、2011年

1
CookieはHTTP / RESTで有効ですが、サーバーはCookieを(セッションとしてではなく)状態として保存しないでください。CookieはHMACのような値を格納できますが、他の場所で状態を検索せずに逆アセンブルできます。
Bruce Alderson、2011年

14

RESTの基本

RESTには統一されたインターフェース制約があります。これは、RESTクライアントが実際のRESTサービスのアプリケーション固有の詳細ではなく標準に依存する必要があることを示しているため、RESTクライアントは小さな変更によって中断されず、おそらく再利用できます。

したがって、RESTクライアントとRESTサービスの間には規約があります。基になるプロトコルとしてHTTPを使用する場合、次の標準が契約の一部です。

  • HTTP 1.1
    • メソッド定義
    • ステータスコードの定義
    • キャッシュ制御ヘッダー
    • acceptおよびcontent-typeヘッダー
    • 認証ヘッダー
  • IRI(utf8 URI
  • 本体(1つ選択)
    • 登録されたアプリケーション固有のMIMEタイプ(例:maze + xml)
    • ベンダー固有のMIMEタイプ、たとえばvnd.github + json
    • 汎用MIMEタイプ
      • アプリケーション固有のRDF語彙。例:ld + jsonhydraschema.org
      • アプリケーション固有のプロファイル。例:hal + json&プロファイルリンクパラメータ(推測)
  • ハイパーリンク
    • それらを何に含めるか(1つ選択)
      • リンクヘッダーで送信する
      • ハイパーメディアレスポンス、たとえばhtml、atom + xml、hal + json、ld + json&hydraなどを送信する...
    • 意味論
      • IANAリンク関係を使用し、おそらくカスタムリンク関係を使用します
      • アプリケーション固有のRDF語彙を使用する

RESTにはステートレス制約があり、RESTサービスとクライアント間の通信はステートレスでなければならないことを宣言しています。これは、RESTサービスがクライアントの状態を維持できないため、サーバー側のセッションストレージを保持できないことを意味します。すべてのリクエストを認証する必要があります。したがって、たとえば、HTTP基本認証(HTTP標準の一部)は、すべての要求でユーザー名とパスワードを送信するため、問題ありません。

あなたの質問に答えるために

  1. はい、可能です。

    ちょうど言うと、クライアントはIRI構造を気にしません。クライアントは、リンク関係またはリンクデータ(RDF)属性を持つリンクをたどるため、セマンティクスを気にします。

    IRIについて唯一重要なことは、単一のIRIが単一のリソースのみを識別しなければならないということです。ユーザーのような単一のリソースで、多くの異なるIRIを持つことができます。

    のような素晴らしいIRIを使用する理由は非常に簡単です/users/123/password。IRIを読んだだけで理解できれば、ルーティングロジックをサーバーに書き込む方がはるかに簡単です。

  2. PUT、PATCH、OPTIONSなどの動詞がありますが、それ以上は必要ありません...新しい動詞を追加する代わりに、新しいリソースを追加する方法を学ぶ必要があります。

    activate_login -> PUT /login/active true deactivate_login -> PUT /login/active false change_password -> PUT /user/xy/password "newpass" add_credit -> POST /credit/raise {details: {}}

    (ログインは、ステートレスな制約のため、RESTの観点からは意味がありません。)

  3. ユーザーは、問題が存在する理由を気にしません。彼らは成功またはエラーがあるかどうか、そしておそらく彼らが理解できるエラーメッセージだけを知りたいと思っています。たとえば、「申し訳ありませんが、あなたの投稿を保存できませんでした。」など

    HTTPステータスヘッダーは、標準のヘッダーです。他のすべては私が思う体内にあるべきです。単一のヘッダーでは、たとえば詳細な多言語エラーメッセージを説明するには不十分です。

  4. ステートレス制約(キャッシュおよび階層化システム制約とともに)により、サービスが適切にスケーリングされます。あなたがクライアントで同じことをすることができるとき、あなたは確かにサーバーで何百万ものセッションを維持する必要はありません...

    ユーザーがメインクライアントを使用してアクセスを許可すると、サードパーティクライアントはアクセストークンを取得します。その後、サードパーティのクライアントはすべてのリクエストでアクセストークンを送信します。たとえば、すべてのリクエストに署名できるなど、より複雑なソリューションがあります。詳細については、OAuthのマニュアルを確認してください。

関連文献


11

あなたが言った例については、私は以下を使用します:

activate_login

POST /users/1/activation

deactivate_login

DELETE /users/1/activation

パスワードを変更する

PUT /passwords (これは、ユーザーが認証されていることを前提としています)

add_credit

POST /credits (これは、ユーザーが認証されていることを前提としています)

エラーの場合は、リクエストを受け取った形式でエラーを本文に返します。したがって、次のメッセージが表示された場合:

DELETE /users/1.xml

あなたはXMLで応答を送り返すでしょう、同じことがJSONなどにも当てはまります...

認証には、http認証を使用する必要があります。


1
私はcreateURIの一部として使用しません(URIは名詞でなければならず、HTTPメソッドはそれらの名詞を操作する動詞である必要があります)。代わりに、/users/1/active単純なブール値にすることができるようなそのリソースに1または0をPUTして設定します。
フリード

そうです、私は/ createを取り出しました。シングルトンリソースへの投稿である必要があります。
jonnii

3
activationの名前でリソースを明示的に操作および管理しない限り、URIでも使用しません/users/1/activation。その上でGETは何をしますか?PUTは何をしますか?URIを検証しているように感じます。また、コンテンツタイプネゴシエーションについても、URIを省略してヘッダーに挿入するのが最善Acceptです。
Cheeso 2010

6
  1. 新しいリソースURIがどのように見えるかわからない場合(新しいユーザーを作成し、アプリケーションが新しいユーザーにIDを割り当てる場合)にpostを使用します。リソースがどのように表現されるかがわかっているリソースを更新または作成するためのPUT :PUT /myfiles/thisismynewfile.txt)
  2. メッセージの本文でエラーの説明を返す
  3. HTTP認証を使用できます(十分な場合)Webサービスはステートレスである必要があります

5

(最初のパスとして)PUT既存のエンティティの更新にのみ使用することをお勧めします。POST新しいものを作成するために使用する必要があります。すなわち

/api/users     when called with PUT, creates user record

私には正しいとは思わない。ただし、最初のセクションの残りの部分(動詞の用法など)は論理的に見えます。


たぶん誰かがこれは彼の質問に対する答えではないと思ったでしょう
lubos hasko

6
新しいエンティティを作成するためのPUTとPOSTの比較では、呼び出し元がリソース名を制御するときにPUTを使用するため、呼び出し先が新しいリソース名を制御するときにPUTを使用できます(この例のように)。
SteveD

5

詳細、ただしhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec9.htmlの HTTP 1.1メソッド仕様からコピー

9.3 GET

GETメソッドは、Request-URIで識別される情報(エンティティーの形式)を取得します。Request-URIがデータ生成プロセスを参照している場合、そのテキストがたまたまプロセスの出力である場合を除き、プロセスのソーステキストではなく、応答のエンティティとして返されるのは生成されたデータです。

リクエストメッセージにIf-Modified-Since、If-Unmodified-Since、If-Match、If-None-Match、またはIf-Rangeヘッダーフィールドが含まれている場合、GETメソッドのセマンティクスは「条件付きGET」に変わります。条件付きGETメソッドは、エンティティが条件付きヘッダーフィールドで記述された状況でのみ転送されることを要求します。条件付きGETメソッドは、複数のリクエストを要求したり、クライアントがすでに保持しているデータを転送したりせずに、キャッシュされたエンティティを更新できるようにすることで、不要なネットワーク使用量を減らすことを目的としています。

リクエストメッセージにRangeヘッダーフィールドが含まれている場合、GETメソッドのセマンティクスは「部分的なGET」に変わります。部分的なGETは、セクション14.35で説明されているように、エンティティの一部のみが転送されることを要求します。部分的なGETメソッドは、クライアントがすでに保持しているデータを転送せずに部分的に取得されたエンティティを完了できるようにすることで、不要なネットワーク使用量を減らすことを目的としています。

GET要求への応答は、セクション13で説明されているHTTPキャッシングの要件を満たしている場合にのみキャッシュ可能です。

フォームに使用する場合のセキュリティに関する考慮事項については、セクション15.1.3を参照してください。

9.5投稿

POSTメソッドを使用して、オリジンサーバーがリクエストに含まれるエンティティを、Request-LineのRequest-URIで識別されるリソースの新しい下位として受け入れることをリクエストします。POSTは、以下の機能をカバーする統一された方法を可能にするように設計されています。

  - Annotation of existing resources;
  - Posting a message to a bulletin board, newsgroup, mailing list,
    or similar group of articles;
  - Providing a block of data, such as the result of submitting a
    form, to a data-handling process;
  - Extending a database through an append operation.

POSTメソッドによって実行される実際の機能はサーバーによって決定され、通常はRequest-URIに依存します。投稿されたエンティティは、ファイルがそれを含むディレクトリに従属している、ニュース記事が投稿先のニュースグループに従属している、またはレコードがデータベースに従属しているのと同じように、そのURIに従属しています。

POSTメソッドによって実行されるアクションは、URIで識別できるリソースにならない場合があります。この場合、応答に結果を説明するエンティティが含まれているかどうかに応じて、200(OK)または204(コンテンツなし)が適切な応答ステータスです。

オリジンサーバーでリソースが作成されている場合、応答は201(作成済み)である必要があり、リクエストのステータスを記述し、新しいリソースを参照するエンティティと、ロケーションヘッダー(セクション14.30を参照)を含む必要があります。

このメソッドへの応答は、応答に適切なCache-ControlまたはExpiresヘッダーフィールドが含まれていない限り、キャッシュできません。ただし、303(その他を参照)応答を使用して、ユーザーエージェントにキャッシュ可能なリソースを取得するように指示できます。

POSTリクエストは、セクション8.2に記載されているメッセージ送信要件に従う必要があります。

セキュリティに関する考慮事項については、セクション15.1.3を参照してください。

9.6置く

PUTメソッドは、囲まれたエンティティが指定されたRequest-URIの下に格納されることを要求します。Request-URIが既存のリソースを参照している場合、囲まれたエンティティは、起点サーバーに存在するエンティティの変更バージョンと見なされるべきです(SHOULD)。Request-URIが既存のリソースを指さず、そのURIが要求元のユーザーエージェントによって新しいリソースとして定義できる場合、オリジンサーバーはそのURIでリソースを作成できます。新しいリソースが作成された場合、配信元サーバーは201(Created)応答を介してユーザーエージェントに通知する必要があります。既存のリソースが変更された場合、200(OK)または204(No Content)応答コードのいずれかを送信して、要求が正常に完了したことを示す必要があります。Request-URIでリソースを作成または変更できなかった場合、問題の性質を反映する適切なエラー応答を与える必要があります。エンティティの受信者は、理解または実装していないContent- *(Content-Rangeなど)ヘッダーを無視してはならず(MUST)、そのような場合は501(Not Implemented)応答を返さなければなりません(MUST)。

リクエストがキャッシュを通過し、Request-URIが現在キャッシュされている1つ以上のエンティティを識別する場合、それらのエントリは古いものとして扱われる必要があります(SHOULD)。このメソッドへの応答はキャッシュできません。

POST要求とPUT要求の基本的な違いは、Request-URIの異なる意味に反映されています。POSTリクエストのURIは、囲まれたエンティティを処理するリソースを識別します。そのリソースは、データを受け入れるプロセス、他のプロトコルへのゲートウェイ、または注釈を受け入れる個別のエンティティの場合があります。対照的に、PUTリクエストのURIは、リクエストに含まれるエンティティを識別します。ユーザーエージェントは意図されているURIを認識しており、サーバーは他のリソースにリクエストを適用してはなりません。サーバーがリクエストを別のURIに適用することを望む場合、

301(永久に移動)応答を送信する必要があります。次に、ユーザーエージェントは、リクエストをリダイレクトするかどうかに関して独自の決定を行うことができます。

単一のリソースは、多くの異なるURIによって識別される場合があります。たとえば、記事には、特定の各バージョンを識別するURIとは別の「現在のバージョン」を識別するためのURIがある場合があります。この場合、一般的なURIに対するPUTリクエストにより、他のいくつかのURIがオリジンサーバーによって定義される可能性があります。

HTTP / 1.1は、PUTメソッドが配信元サーバーの状態にどのように影響するかを定義していません。

PUTリクエストは、セクション8.2に記載されているメッセージ送信要件に従う必要があります。

特定のエンティティヘッダーに特に指定されていない限り、PUTリクエストのエンティティヘッダーは、PUTによって作成または変更されたリソースに適用する必要があります(SHOULD)。

9.7削除

DELETEメソッドは、起点サーバーがRequest-URIで識別されるリソースを削除することを要求します。このメソッドは、オリジンサーバーでの人間の介入(または他の手段)によってオーバーライドされる場合があります。オリジンサーバーから返されたステータスコードがアクションが正常に完了したことを示している場合でも、クライアントは操作が実行されたことを保証できません。ただし、サーバーは、応答が与えられたときにリソースを削除するか、アクセスできない場所に移動することを意図していない限り、成功を示すべきではありません(SHOULD NOT)。

成功した応答は、応答にステータスを説明するエンティティが含まれている場合は200(OK)、アクションがまだ実行されていない場合は202(承認済み)、アクションが実行されているが応答に含まれていない場合は204(コンテンツなし)であるべきです(SHOULD)。エンティティ。

リクエストがキャッシュを通過し、Request-URIが現在キャッシュされている1つ以上のエンティティを識別する場合、それらのエントリは古いものとして扱われる必要があります(SHOULD)。このメソッドへの応答はキャッシュできません。


2

REST戻りコードについて:HTTPプロトコルコードとREST結果を混在させるのは間違っています。

しかし、多くの実装がそれらを混合しているのを見たので、多くの開発者が私に同意しないかもしれません。

HTTP戻りコードは、HTTP Requestそれ自体に関連しています。REST呼び出しは、ハイパーテキスト転送プロトコル要求を使用して行われ、呼び出されたRESTメソッド自体よりも低いレベルで機能します。RESTは概念/アプローチであり、その出力はビジネス/論理結果であり、HTTP結果コードはトランスポートですです。

たとえば、/ users /を呼び出したときに "404 Not found"を返すと混乱を招きます。

  • URIが間違っている(HTTP)
  • ユーザーが見つかりません(REST)

「403 Forbidden / Access Denied」とは、

  • 特別な許可が必要です。ブラウザは、ユーザー/パスワードを尋ねることによってそれを処理できます。(HTTP)
  • サーバーで構成されているアクセス権が間違っています。(HTTP)
  • 認証する必要があります(REST)

また、リストは「500サーバーエラー」(Apache / Nginx HTTPスローエラーまたはRESTのビジネス制約エラー)またはその他のHTTPエラーなどで続行される場合があります。

コードから、失敗の理由、HTTP(トランスポート)の失敗、またはREST(論理)の失敗の原因を理解するのは困難です。

HTTPリクエストが物理的に正常に実行された場合、レコードが見つかったかどうかに関係なく、常に 200コードを返す必要あります。URIリソースが見つかり、httpサーバーによって処理されたためです。はい、空のセットが返される場合があります。200のhttp結果として空のウェブページを受け取ることは可能ですか?

これの代わりに、200個のHTTPコードと空の配列/オブジェクトを含むJSONを返すか、ブールの結果/成功フラグを使用して、実行された操作のステータスを通知できます。

また、インターネットプロバイダーによっては、リクエストを傍受して404 HTTPコードを返す場合があります。これは、データが見つからないという意味ではありませんが、トランスポートレベルで何か問題があります。

Wikiから:

2004年7月、英国の通信プロバイダーであるBT GroupはCleanfeedコンテンツブロッキングシステムを展開しました。このシステムは、Internet Watch Foundationによって違法である可能性があると識別されたコンテンツのリクエストに対して404エラーを返します。他のISPは、同じ状況でHTTP 403「禁止」エラーを返します。検閲を隠す手段として偽の404エラーを使用する慣行は、タイとチュニジアでも報告されています。2011年の革命以前は検閲が厳しかったチュニジアでは、人々は偽の404エラーの性質に気づき、「目に見えない検閲者」を表す「Ammar 404」という架空のキャラクターを作成しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.