REST API-PUT DELETE POST GETを使用する理由


155

それで、私はREST APIの作成に関するいくつかの記事を調べていました。そして、それらのいくつかは、すべてのタイプのHTTPリクエストの使用を提案しますPUT DELETE POST GET。たとえばindex.phpを作成し、次のようにAPIを記述します。

$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
    break;
  case 'POST':
    ....some post action.... 
    break;
  case 'GET':
    ....some get action.... 
    break;
  case 'DELETE':
    ....some delete action.... 
    break;
}

はい、当然です-私は(まだ)Webサービスについてあまり知りません。しかし、通常のまたは(メソッド名とすべてのパラメーターを含む)を介してJSONオブジェクトを受け入れるだけで、JSONで応答する方が簡単ではないでしょうPOSTGET。私たちは、簡単にシリアル化/デシリアライズPHPの経由することができますjson_encode()json_decode()、別のHTTPリクエストメソッドに対処しなくても、私たちはそのデータをやりたいです。

何か不足していますか?

更新1:

OK-さまざまなAPIを調べXML-RPCJSON-RPCSOAPRESTについて多くを学んだ後、このタイプのAPIは適切であるという結論に達しました。実際、スタック交換はサイトでこのアプローチをかなり使用しており、私はこれらの人々がStack Exchange APIを実行していることを知っていると思います


4
JSONペイロードを強制する理由 JSONがなく、プレーンな古いGETの場合はどうなりますか?
Mike DeSimone、2011年

回答:


200

アイデアREプレゼンテーションSテイトT ransferは、可能な最も簡単な方法でデータにアクセスする話ではありません。

postリクエストを使用してJSONにアクセスすることを提案しました。これは、データにアクセス/操作するための完全に有効な方法です。

RESTは、データへの有意義なアクセスのための方法論です。RESTでリクエストを見ると、データで何が起こっているかがすぐにわかります。

例えば:

GET: /cars/make/chevrolet

シボレーカーのリストを返す可能性があります。 良いREST APIは、さらにいくつかの出力クエリ文字列内のオプションのように組み込むかもしれません?output=jsonまたは?output=htmlアクセサ情報がでエンコードする必要がありますどのような形式を決定することが可能になります。

どのようにRESTのAPIに合理的に組み込んデータ型にについて考えるのビットの後、私は、データの型を指定するための最良の方法は、そのように明示的に既存のファイル拡張子を経由だろうと結論付けました.js.json.htmlまたは、.xml。ファイル拡張子が欠落していると、デフォルトのフォーマット(JSONなど)になります。サポートされていないファイル拡張子は、501 Not Implementedステータスコードを返す可能性があります

もう一つの例:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

関連する色で新しいシボレーマリブをdbに作成する可能性があります。私が言う可能性が REST APIは、直接データベース構造に関連する必要はありませんよう。真のデータが保護されるようにするための単なるマスキングインターフェイスです(データベース構造のアクセサーやミューテーターのようなものと考えてください)。

次に、べきの問題に移る必要があります。通常、REST はHTTPを介してCRUDを実装します。HTTPは使用していますGETPUTPOSTおよびDELETE要求のため。

RESTの非常に単純な実装では、次のCRUDマッピングを使用できます。

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

この実装には問題があります:Postは非べき等メソッドとして定義されています。つまり、同じPostメソッドを続けて呼び出すと、サーバーの状態が異なります。Get、Put、Deleteはべき等です。つまり、それらを複数回呼び出すと、サーバーの状態は同じになります。

これは、次のようなリクエストを意味します。

Delete: /cars/oldest

実際には次のように実装できます。

Post: /cars/oldest?action=delete

一方

Delete: /cars/id/123456

1回呼び出すか、1000回呼び出すと、同じサーバー状態になります。

oldestアイテムの削除を処理するより良い方法は、以下をリクエストすることです。

Get: /cars/oldest

そして使用IDするために、結果のデータからのdelete要求を:

Delete: /cars/id/[oldest id]

このメソッドの問題は、リクエスト/carsされたとき/oldestdelete発行されたときに別のアイテムが追加された場合です。


3
@Andreそれはいくつかの理由の組み合わせです:HTTPガイドラインに従うことは、物事が変化したときに(おそらく)後方互換性の問題が少なくなることを意味します。POSTを介してHTMLフォームを使用すると、同じデータの複数の送信についてユーザーに警告が表示されます(これはべき等でないトランザクションを防ぐためです)。明確に定義されたベストプラクティスに従うと、..ベストプラクティスになります。Restは特定の実装を考慮して定義されていないため、必要に応じてそれを使用できます。HTTPのすべてのエラーコードとリクエストメソッドを利用することをお勧めしますが、好きなように実行できます
zzzzBov

4
したがって、この回答の問題(それはまともな回答ですが、完全ではありません)は、彼が尋ねた主な質問に対応していないということです:カスタムJSONデータではなくHTTP動詞とURIを使用する理由(おそらく何らかのJSONベースのAPI呼び出し構文)。カスタムJSON構文を作成して、「すぐに...データで何が起こっているかをすぐにわかるようにする」ことができます。あなたができないことは、すべてのREST規約に従うAPIでできるように、HTTPの上に組み込まれた機能とネットワークレイヤーを簡単に使用することです。もちろん、私の答えは完璧ではありません;)
Merlyn Morgan-Graham

4
@Andre:wikiエントリが使用する例は、認証、キャッシング、コンテンツタイプネゴシエーションです。私はそれについてもっと考えていますが、RPCスタイルのインターフェイスでこれらを使用できるかもしれませんが、多くの場合、独自のシステムを最初から実装するか、既存のシステムへの統合をコード化するのが魅力です。RESTを使用すると、組み込みの統合を使用し、それをWebサーバーで管理できます。これは、結合が緩いことを意味します。つまり、実装する必要が少なくなることを意味します。また、コードとテストへの影響が少なく、将来的にオプションを変更するためのアプリの柔軟性が高くなります。
Merlyn Morgan-Graham

10
DELETE:/ cars / oldestの代わりに、GET:/ cars / oldestに続いてDELETEを実行しますか?このようにして、2つの独立したべき等コマンドがあります。
Neil

3
+1; これは良い答えだと思います(楽しさと利益のためにもう一度説明します)。POST: /cars/oldestDELETEの代わりになることは、あまり意味がありません。のようなもの- POST: /cars/oldest/deleteおそらく、ニールのソリューションの方が好きだと思います。直接削除が彼のget-id-delete-idソリューションよりも優れている唯一の利点は、原子性です。そのようなことを実装する前に、不自然なシナリオで明確なビジネス上の正当化が必要です。すべてのオブジェクト/ URLですべての動詞をサポートする必要はありません。
Merlyn Morgan-Graham

39

これはセキュリティと保守性の問題です。

安全な方法

可能な限り、潜在的な脆弱性を制限するために、GETやHEADなどの「安全な」(一方向の)メソッドを使用する必要があります。

べき等法

可能な限り、GET、HEAD、PUT、DELETEなどの「べき等」メソッドを使用する必要があります。これらのメソッドは副作用があり得ないため、エラーが発生しにくく、制御しやすくなっています。

ソース


1
申し訳ありませんが、PUTおよびDELETEのべき等メソッドはどうですか?それらはサーバーとそのデータの状態に影響します!
Mahmoud Al-Qudsi 2011年

27
@コンピュータ:同じPUTまたは同じDELETEを実行すると、同じ最終状態になります。それが「べき等」の意味です。
イグナシオバスケスエイブラムス

4
より明確にするために:オペレーションFは、単一のアプリケーションとそれに続く複数のアプリケーションの両方が同じ結果を返す場合、べき等です。より正確には、F(x)= F(F(x))の場合に限り、Fはべき等です。たとえば、削除はべき等です。これは、アイテムを1回削除するか、数回削除しても、結果は同じです。アイテムは、最初の削除アプリケーションで1回だけ削除され、2番目または3番目の削除アプリケーションでは何も起こりません。
qartal 2016

1
ただし、作成に関しては、createコマンドを使用して新しいレコードを作成し、同じコマンドを再度発行すると、(おそらく)2つのレコードが作成されます(どちらも同じ情報を反映しています)。
qartal 2016

qartal-べき等の関数定義は 'F(X)= F(X)F(X)'でなければなりません。それを言い表すのにいい方法です。
Gerard ONeill 2017年

26

つまり、RESTは動詞よりも名詞を強調します。APIが複雑になると、コマンドではなく、さらに多くのものを追加します。


2
これで頭を回すのに少し苦労しました。このポスト(lornajane.net/posts/2013/... URIはその後、名詞のみを含める必要がありますように、動詞はHTTPリクエストから来るべきであることは)私のために少しをそれをクリア
icc97

9

あなたは尋ねました

通常の$ _POSTを介してJSONオブジェクトを受け入れ、JSONで応答する方が簡単ではないでしょうか

RESTに関するウィキペディアから:

RESTfulアプリケーションは、既存の明確に定義されたインターフェイスと、選択したネットワークプロトコルによって提供されるその他の組み込み機能の使用を最大化し、その上に新しいアプリケーション固有の機能の追加を最小限に抑えます

私が見た(少し)ことから、これは通常、既存のHTTP動詞の使用を最大化し、できるだけ強力で自明なサービスのURLスキームを設計することによって達成されると思います。

カスタムデータプロトコル(SOAPやJSONなどの標準プロトコルの上に構築されている場合でも)は推奨されていません。RESTイデオロギーに最も適合するように最小化する必要があります。

一方、SOAP RPC over HTTPは、通常、HTTP 'POST'動詞にオーバーレイされる、名詞と動詞(たとえば、getUsers()、savePurchaseOrder(...))の新しい任意の語彙を定義することを各アプリケーション設計者に奨励します。これは、認証、キャッシング、コンテンツタイプネゴシエーションなど、HTTPの既存の機能の多くを無視し、アプリケーションデザイナーがこれらの機能の多くを新しいボキャブラリ内で再発明することを余儀なくされる可能性があります。

作業する実際のオブジェクトは、任意の形式にすることができます。アイデアは、ユーザーがそれらのリソースに対して実行したい操作(クエリ、状態管理/変更、削除)を公開するために、可能な限り多くのHTTPを再利用することです。

あなたは尋ねました

何か不足していますか?

RESTとURI構文/ HTTP動詞自体について、知っておくべきことがたくさんあります。たとえば、一部の動詞はべき等ですが、そうでないものもあります。私はあなたの質問でこれについて何も見なかったので、私はそれに飛び込むことを試みませんでした。他の回答とウィキペディアには、どちらも多くの良い情報があります。

また、本当に安らかなAPIを使用している場合に利用できる、HTTPの上に構築されたさまざまなネットワークテクノロジーについて学ぶべきことがたくさんあります。私は認証から始めます。


8

データ型の定義に拡張機能を使用することに関して。MailChimp APIがそれを実行していることに気づきましたが、これは良い考えではないと思います。

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

私のサウンドは良い考えのようですが、「古い」アプローチの方が良いと思います-HTTPヘッダーを使用する

GET /xxx/cars/1
Accept: application/json

また、HTTPヘッダーはクロスデータタイプの通信に適しています(必要な場合)

POST /zzz/cars
Content-Type: application/xml     <--- indicates we sent XML to server
Accept: application/json          <--- indicates we want get data back in JSON format  

4

何か不足していますか?

はい。;-)

この現象は、均一なインターフェース制約のために存在します。RESTは、ホイールを再発明するのではなく、既存の標準を使用することを好みます。HTTP標準は、非常にスケーラブルであることが既に証明されています(Webはしばらくの間機能しています)。なぜ壊れていないものを直さなければならないのですか?

注:クライアントをサービスから切り離したい場合は、統一されたインターフェース制約が重要です。これは、クラスを相互に分離するためにクラスのインターフェースを定義するのと似ています。Ofc。ここでは、統一されたインターフェースは、HTTPMIMEタイプURIRDFリンクされたデータvocabsヒドラvocabなどの標準で構成されています。


2

プログラミングでは、優れたセマンティクスが重要です。

GET / POST以外のメソッドを使用すると、コードが読みやすくなり、保守が容易になるため、役立ちます。

どうして?

あなたはGETがあなたのAPIからデータを取得することを知っているからです。POSTがシステムに新しいデータを追加することを知っています。PUTが更新を行うことを知っています。DELETEは行などを削除します。

通常はRESTFUL Webサービスを構造化して、メソッドと同じ名前の関数コールバックを持つようにします。

私はPHPを使用しているため、function_existsを使用します(呼び出されたと思います)。関数が存在しない場合は、405(メソッドは許可されていません)をスローします。


2

Bill Venners:「なぜRESTが失敗したのか」というブログ投稿で、GET、POST、PUT、DELETEの4つのHTTP動詞がすべて必要であると述べ、ブラウザベンダーはGETとPOSTのみを必要としていると嘆いた」なぜ4つすべてが必要なのか動詞?GETとPOSTでは不十分なのはなぜですか?

エリオットラスティハロルド: HTTPには、GET、POST、PUT、DELETEという4つの基本的なメソッドがあります。ほとんどの場合、GETが使用されます。安全で副作用のないものに使用されます。GETは、ブックマーク、キャッシュ、リンク、プロキシサーバー経由の通過が可能です。これは非常に強力な操作であり、非常に便利な操作です。

対照的に、POSTはおそらく最も強力な操作です。それは何でもできます。何が発生するかについては制限がありません。その結果、非常に注意する必要があります。ブックマークしません。キャッシュしません。あなたはそれをプリフェッチしません。ユーザーに尋ねずにPOSTを実行することはありません。これを行いますか?ユーザーがボタンを押すと、一部のコンテンツをPOSTできます。しかし、ページのすべてのボタンを見て、ランダムにボタンを押し始めるわけではありません。対照的に、ブラウザはページ上のすべてのリンクを調べてそれらをプリフェッチするか、または次にたどられる可能性が最も高いと思われるリンクをプリフェッチします。実際、一部のブラウザーやFirefox拡張機能、その他のさまざまなツールは、ある時点でそうしようとしています。

PUTとDELETEは、GETとPOSTの中間にあります。PUTまたはDELETEとPOSTの違いは、PUTとDELETEが*べき等であるのに対し、POSTはそうでないということです。PUTとDELETEは、必要に応じて繰り返すことができます。サイトに新しいページをアップロードしようとしているとしましょう。新しいページを作成したいとします http://www.example.com/foo.htmlにます。なので、コンテンツを入力し、そのURLにPUTします。サーバーは、指定されたURLにそのページを作成します。さて、何らかの理由でネットワーク接続がダウンしたとしましょう。確かではありませんが、リクエストは処理されましたか?多分ネットワークが遅いです。プロキシサーバーに問題がある可能性があります。したがって、何度でも、または何度でも、何度でも試すことができます。同じドキュメントを同じURLに10回PUTすることは、1回置くことと何の違いもないためです。DELETEについても同様です。何かを10回削除できます。これは、1回削除するのと同じです。

対照的に、POSTは毎回異なる何かを引き起こす可能性があります。購入ボタンを押してオンラインストアからチェックアウトするとします。そのPOSTリクエストを再度送信すると、カート内のすべてをもう一度購入してしまう可能性があります。もう一度送った場合は、3回目の購入です。そのため、ユーザーの明示的な同意なしにブラウザがPOST操作を繰り返す場合は、POSTが2回実行すると2つ、3回実行すると3つ発生する可能性があるため、非常に注意が必要です。PUTとDELETEを使用すると、リクエスト数がゼロと1の間に大きな違いがありますが、1つのリクエストと10の間に違いはありません。

詳細については、URLにアクセスしてください。 http://www.artima.com/lejava/articles/why_put_and_delete.html

更新:

べき等法 べき等等HTTPメソッドは、さまざまな結果なしに何度も呼び出すことができるHTTPメソッドです。メソッドが1回だけ呼び出されても、10回以上呼び出されても問題ありません。結果は同じになるはずです。繰り返しますが、これはリソースにではなく結果にのみ適用されます。この情報は、(現在の)リソース表現で共有されていない限り、(更新タイムスタンプのように)操作できます。

次の例を検討してください。

a = 4;

a ++;

最初の例はべき等です。このステートメントを何回実行しても、aは常に4になります。2番目の例はべき等ではありません。これを10回実行すると、5回実行した場合とは異なる結果になります。どちらの例もaの値を変更しているため、どちらも安全ではないメソッドです。


1
新しいページの例については、POSTを更新のためにPUTしている間は、POSTをそのように使用しないでください。新しいページの作成は、毎回新しい結果を生成するプロセスですが、同じ編集は何度でも繰り返し実行され、同じ結果を毎回繰り返します。いい言い回しと説明ですが。
Spyryto 2018年

0

基本的にRESTは(wiki):

  1. クライアントサーバーアーキテクチャ
  2. 無国籍
  3. キャッシュ可能性
  4. 階層化システム
  5. オンデマンドコード(オプション)
  6. 均一なインターフェース

RESTはプロトコルではなく、原則です。さまざまなURIとメソッド-いわゆるベストプラクティス。

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