27

ここにいる多くの開発者は、 RESTful APIからのGETリクエストがリクエストされたリソースのIDを返す必要があるかどうかについて、友好的な(宗教的と言う人もいます)議論をしています。次のGETリクエストを想定します。

http://my.api.com/rest/users/23

これは現在次を返します:

{"name": "Jim", "age": 40, "favoriteColor": "blue"}

結果セットに「id」がないことに注意してください。

この問題と戦っているキャンプは基本的に4つあります。

キャンプ#1:発信者がGETリクエストを行うとき、彼らはすでにIDを知っています。したがって、結果セットにはIDを含めないでください。呼び出し元がUI編集を有効にするためにこのデータを必要とする場合、呼び出し元はID 23をパススルーする必要があります。おそらく、メンバー{"id":23}をJSONに手動で追加します。
キャンプ#1の人々はまた、結果セットにIDが存在することは、この値が変更可能であることを示していると主張していますが、もちろん変更できません。

キャンプ#2: IDがないと、JSON結果セットをUIフォームの編集/更新操作にネイティブに使用できません。代わりに、AJAXコールバックメカニズムがIDフィールドを渡し、手動で結果セットに追加する必要があります。これは扱いにくく、エラーが発生しやすいようです。UI担当者は、結果セットが存在するはずのデータ、つまりIDが欠落しているように「感じる」と主張しています。

キャンプ#3:これらの人々は一貫性を心配しています。APIによって返されるユーザーオブジェクトのコレクションがある場合、これらのオブジェクトにはIDが含まれている必要があります。したがって、一貫性を保つために、シングルトンバージョンのGETにはIDも含める必要があります。

キャンプ#4:これらの人々は、ユーザーのGETリクエストが、IDを含むハイパーメディアまたはSelfLinksの形式でメタデータを返す可能性があることを示唆しています。

これは難解な「Who'sRight?」ではありません。どちらか。私たちが採用するアプローチは、APIの形状を決定し、新しい数週間にわたる複数の開発者の作業負荷に影響を与えます。

4

2 に答える 2

23

これは意見の問題であり、Stackoverflowが見たいと思うような質問ではありません。いずれにせよ、私は私のものを提供します。

オブジェクトまたはリソースの状態の表現を返します。IDはその表現の一部であるため、JSONパケットに含める必要があります。これはリソースのプロパティです。発信者がIDを知っているかどうかは、特に議論に密接に関係しているわけではありません。キャンプ#1は不安定な地面にあります。

コレクションについてあなたが提起するポイントは非常に関連性があります。1つの表現をretrieve-1操作に使用し、別の表現をretrieve-N操作に使用することは意味がありますか?私はそうは思わない。

ただし、直面している問題はより一般的です。クライアントに転送される表現にどのデータを含める必要があり、どのような状況であるのでしょうか。 場合によっては、呼び出し元はプロパティの重要なサブセットを気にしないだけです。特に、大量のオブジェクトが取得されるシナリオ(基本的な通信コストと比較してデータの送信コストが高いシナリオ)では、返送されるものを最適化する必要があります。

十分に成熟したすべてのRESTプロトコルには、返されるデータを形成する機能があります。

例については、を参照してください。

  • Facebook Graph API、http://developers.facebook.com/docs/reference/api/
  • StackExchangeAPIv2.0-返されるものを正確に形作るために渡すことができる「フィルター」オブジェクトがあります。
  • CouchDb API-すべてのビューにマップ関数があり、返されるデータを決定します。またinclude_docs、完全なオブジェクトまたはメタデータのみを含めるようにサーバーに指示する包括的なクエリパラメーターがあります。(場合によっては、実際のデータではなく、データの数だけが必要になることがあります。)

Facebookでは、必要なフィールドを明示的に指定できます。

ここに画像の説明を入力してください

stackexchangeAPIは興味深いものです。彼らは、シェーピングをサポートするためにまったく新しいタイプのオブジェクトを定義しました。APIを使用して「フィルター」を定義し、サーバー側に保存できます。次に、クエリでフィルターのIDを使用してフィルターパラメーターを渡します。返されるオブジェクト表現には、フィルターで指定されたすべての属性が含まれます。フィルタがないと、フィールドの「デフォルト」サブセットが得られます。「すべてのフィールド」を取得するには、包括的なフィルターを定義する必要があります。

https://api.stackexchange.com/docs/answersでこれが実際に動作していることを確認できます

...具体的には、フィルター仕様ダイアログを参照してください。

ここに画像の説明を入力してください


物事を行うための単一の正しい方法はありません。サポートする「シェーピング」機能の複雑さと、開発コストおよびAPIを使用するアプリのニーズとのバランスをとる必要があります。

于 2012-07-02T21:00:54.533 に答える
3

古い質問ですが、私はここで何かを探しているので、ここでさらに別の意見があります:

まず、URLは次のようになります。

http://my.api.com/rest/Users/23

いいえ

http://my.api.com/rest/getUsers/23

「GET」は、URLではなくHTTPメソッドにあります。名前を付けるだけですが、わかりやすくするのに役立ちます、IMHO。

これについて考えると、リソースの変更はPUTと同じURLで行う必要があります

PUT http://my.api.com/rest/Users/23

その場合、クライアントはIDではなくURLを追跡する必要があります。リソースがIDフィールドを返すかどうかは関係ありません。それがどこから取得されたかの地図を保持するのはクライアント次第です。

リソースを別のURL、たとえば「http://my.api.com/rest/Users/24」に配置しようとすると、いくつかのシナリオが発生します。

1)http://my.api.com/rest/Users/24はサーバー上にすでに存在し、サーバーはリソースを更新として受け入れます

2)http://my.api.com/rest/Users/24がサーバーに存在せず、次の場合。

a)サーバーはユーザーが存在しないリソースにID(24)を提供していることを受け入れます(非推奨)b)サーバーはPUTをPOSTとして受け入れます

a + bでは、サーバーは新しいリソースを作成します。

それで:

1)クライアントをどれだけ信頼するかに応じて、サーバー上に「チェックイン/チェックアウト」コントロールを作成して、あるリソースを別のリソースで上書きしないようにする必要があります(これはRESTfulですか?)

2)IDを作成するクライアントを受け入れないでください(http://my.api.com/rest/Users/24ではなくhttp://my.api.com/rest/Users/を投稿してください)。また、受け入れないでください。存在しないリソースへのPUT。

編集

したがって、リソースはIDではなくURLによって識別されると思います。つまり、リソースIDは23ではなくhttp://my.api.com/rest/Users/23です。

意味がありますか?

于 2014-02-07T03:10:04.630 に答える