1

HTTP経由でRESTAPIを設計しようとしています。私はこれにまったく慣れていないので、私の仮定やアイデアのいずれかがまったく間違っているかどうか教えてください。

ドメインはミニマルです。製品のデータベースがあり、製品ごとに関連する画像があります。ご覧のとおり、APIは次の2つの方法のいずれかで設計できます。

  1. 各画像をその製品にバンドルして、1つのリソースとして表すことができます。このAPIの短所は、製品を配置または取得するたびに、画像を特に読み取ったり変更したりする必要がない場合でも、画像をネットワーク経由で送信する必要があることです。私の理解では、リソースの完全な表現をPUTまたはGETしないことはRESTfulではありません。また、このシナリオでは、クライアント側での画像のキャッシュは役に立ちません。

  2. 製品と画像を2つの異なるリソースとしてモデル化できます。商品をGETすると、画像のGETに使用できるimage_idが含まれます。このモデルには、2つのHTTPリクエストが必要です。1つは製品を取得し、もう1つは対応する画像を取得します。それほど悪くはないかもしれませんが、すべての製品のリストとその画像を表示したい場合はどうすればよいですか?それから私は突然たくさんのHTTPリクエストを持っています。SSLを使用している場合、これによりパフォーマンスの問題が発生する可能性があると思います。ただし、私のAPIの利用者は、クライアント側で画像をキャッシュすることを選択できるのは良いことです。

では、RESTfulで効率的なAPIをモデル化するにはどうすればよいですか?

4

3 に答える 3

5

データモデルについて考えているのは良いことです。
それに関連して、REST は、データ モデルを完全に非正規化する必要があることを指定または暗示していません。

通常、リソースを取得すると、製品画像などの他の関連リソースへの URL 参照も含まれる情報のパケットを受け取ります。また、製品カテゴリ、製品メーカーなどへの参照を含めることもできます。それぞれが URL または URL の派生元となる ID である可能性があります。次のようなメッセージ:

{
   "id": 123456,
   "description" : "Your basic paperweight",
   "category" : { id: 17717,  "name" : "Home furnishings" },
   "manufacturer": { id : 78783, "name" : "Boeing" },
   "price" : 1.99,
   "imageId" : 109101
}

...次のような URL を意味する場合があります。

http://api.mycompany.com/product/123456   
http://api.mycompany.com/category/17717   
http://api.mycompany.com/manufacturer/78783   
http://api.mycompany.com/image/109101    

...そして、カテゴリ、メーカーなどのリンク先リソースの完全な表現は、元のリソースでは送信されないことに注意してください。これは、部分的に非正規化されたデータ モデルです。

PUTに関するあなたのコメントに関して:

  1. これは意見の問題ですが...多くの開発者にとって、 PUT による部分的な更新を許可することは完全に受け入れられます。したがって、すべてを指定しなくてもリソースを更新できます。既存のフィールドは変更されません。この動作を選択すると、エッジ ケースを処理するときに (サーバー側の) コードが複雑になる可能性があります。たとえば、クライアントはフィールドを消去または削除したいことをどのように示しますか? (null を渡すとうまくいく場合もありますが、一部のデータでは null は意味のある値です。)

  2. PUT について心配する必要はありません。部分的な更新が必要な場合は、クエリ パラメータに動詞 ("partialUpdate" など) を指定して POST を使用すると簡単です。実際、これはロイ・フィールディングが主張していることであり、私には理にかなっています。

部分的な更新は次のようになります。

POST /products/123456?action=partialUpdate 
*headers*

{ 
  "description" : "A fabulous paperweight designed in Sweden, now at a new low price." },
  "price" : 1.78 
}
于 2012-11-24T23:14:00.960 に答える
1

オプション 2 を使用しますが、image_id の代わりに画像の URL を保存します。また、カスタム スクリプトを使用して必要なものを返すことを恐れないでください (たとえば、すべての製品と画像を表示するなど)。REST は設計の目標であり、必ずしも実装の真実ではありません。あなたのデザインは依然として RESTful です。

于 2012-11-24T22:40:16.057 に答える
0

私は他の2つの回答に同意し、オプション番号2を選択する必要があると思います.しかし、製品のリストを取得することについても尋ねられたので、これに関する私の回答です.

GET のみで使用できる別のリソースを使用することを考えてみてください。そのリソースは製品のリストを返します。このようにして、リストを消費するための HTTP 要求は 1 つだけになります。リストが非常に大きくなる可能性がある場合は、何らかのページング メカニズムを実装する必要があります。

たとえば、2,500 個の製品を返品する必要があるが、1,000 個以下の製品を返品することに決めたとします。最初の GET リクエストは最初の 1000 個のアイテムを返し、次の「ページ」、この場合は次の 1000 個の製品を消費するための URL も応答に含め、2 番目のリクエストでは製品 1001 ~ 2000 を URL とともに返します。次の「ページ」へ、この場合は最後の 500 製品です。

その後、消費者は必要に応じて画像を取得することもできます。このリスト オプションを画像にも使用できますが、画像の束は各「ページ」で大幅に小さくする必要があります。画像を使用するためにリスト メカニズムを選択することはお勧めしません。

于 2012-11-26T07:00:19.227 に答える