web-dev-qa-db-ja.com

REST AP​​I-PUT DELETEを使用する理由POST GET?

そのため、REST AP​​Iの作成に関するいくつかの記事を調べていました。そして、それらのいくつかは、PUTDELETEPOSTGETのようなすべてのタイプのHTTPリクエストの使用を提案しています。たとえば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サービスについてはあまり知りません(まだ)。しかし、通常のPOSTまたはGET(メソッド名とすべてのパラメーターを含む)を介してJSONオブジェクトを受け入れるだけの方が簡単ではないでしょうか。そして、同様にJSONで応答します。 PHPのjson_encode()およびjson_decode()を介して簡単にシリアライズ/デシリアライズし、さまざまなHTTPリクエストメソッドを処理することなく、そのデータを使用して任意の処理を実行できます。

何か不足していますか?

更新1:

わかりました-さまざまなAPIを掘り下げて、XML-RPCJSON-RPCSOAPRESTこのタイプのAPIは健全であるという結論に達しました。実際、スタック交換はほとんどのサイトでこのアプローチを使用しており、これらの人々は自分が何をしているかを知っていると思います Stack Exchange API

148
Stann

のアイデア REプレゼン Sテート Transferは、可能な限り簡単な方法でデータにアクセスすることではありません。

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

RESTは、データの意味のあるアクセスの方法論です。 RESTでリクエストを見ると、データで何が起こっているのかがすぐにわかるはずです。

例えば:

GET: /cars/make/chevrolet

シボレー車のリストを返す可能性があります。 優れたREST apiには、?output=json?output=htmlなどのクエリ文字列に出力オプションを組み込むこともできます。これにより、アクセサーが情報のエンコード形式を決定できます。

データ型をREST AP​​Iに合理的に組み込む方法について少し考えた後、データの型を明示的に指定する最良の方法は、.jsなどの既存のファイル拡張子を使用することであると結論付けました。 .json.html、または.xml。欠落しているファイル拡張子は、デフォルトの形式(JSONなど)にデフォルト設定されます。サポートされていないファイル拡張子は、 501 Not Implementedステータスコード を返す可能性があります。

もう一つの例:

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

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

ここで、 idempotence の問題に移る必要があります。通常、RESTはHTTP経由で CRUD を実装します。 HTTPは、リクエストにGETPUTPOSTおよびDELETEを使用します。

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

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

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

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

Delete: /cars/oldest

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

Post: /cars/oldest?action=delete

一方、

Delete: /cars/id/123456

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

oldestアイテムの削除を処理するより良い方法は、以下を要求することです。

Get: /cars/oldest

そして、結果データからIDを使用してdeleteリクエストを作成します。

Delete: /cars/id/[oldest id]

このメソッドの問題は、/carsが要求されてからdeleteが発行されるまでに別の/oldestアイテムが追加された場合です。

195
zzzzBov

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

安全な方法

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

べき等法

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

ソース

38
markus

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

24
Neil

あなたが尋ねた

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

REST のウィキペディアから:

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

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

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

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

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

あなたが尋ねた

何か不足していますか?

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

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

拡張機能を使用してデータ型を定義することに関して。 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  
8
Pawel Cioch

何か不足していますか?

はい。 ;-)

この現象は、 均一なインターフェース制約 のために存在します。 RESTは、車輪を再発明する代わりに、既存の標準を使用するのが好きです。 HTTP標準はすでに非常にスケーラブルであることが証明されています(Webはしばらく動作しています)。壊れていないものを修正する必要があるのはなぜですか?!

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

4
inf3rno

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

GET/POST以外のメソッドを使用すると、コードの可読性が向上し、保守が容易になるため便利です。

どうして?

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

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

私はPHPを使用しているので、function_existsを使用します(と呼ばれると思います)。関数が存在しない場合、405(METHOD NOT ALLOWED)をスローします。

1
HumbleWebDev

Bill Venners:「Why REST Failed」というタイトルのブログ投稿で、4つのHTTP動詞すべてが必要であると言いました。GET、 POST、PUT、およびDELETE—そしてブラウザーベンダーはGETとPOSTだけだと嘆きました。」なぜ4つの動詞すべてが必要なのですか?GETとPOSTが十分ではないのはなぜですか?

Elliotte Rusty Harold:HTTPには、GET、POST、PUT、DELETEの4つの基本メソッドがあります。ほとんどの場合、GETが使用されます。安全で、副作用を引き起こさないものに使用されます。 GETは、ブックマーク、キャッシュ、リンク、プロキシサーバー経由で渡すことができます。これは非常に強力な操作であり、非常に便利な操作です。

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

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

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

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

更新:

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

以下の例を考慮してください。

a = 4;

a ++;

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

1
Bimal Das

基本的にRESTは( wiki ):

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

RESTはプロトコルではなく、原則です。さまざまなURIと方法-ベストプラクティスと呼ばれる人。

0
M-A-X