5

私は RESTful API の設計と実装を依頼され、ベスト プラクティスを調査してきましたが、これまでのところ、リソース表現についてはお粗末な概念しかありません。私が見つけた利用可能な例のほとんどは、一連の GET を使用して接続された構造をたどる API クライアントに重点を置いているようです。

私は見ました:

http://www.restapitutorial.com/media/RESTful_Best_Practices-v1_1.pdf

http://www.youtube.com/watch?v=HW9wWZHWhnI

他のオンライン リソースの中でも (2 つのリンクに限定されているため、すべてをリストすることはできません)。それらはすべて素晴らしいですが、私の設計上の質問には実際には対応していません。

ほとんどのベスト プラクティス ドキュメントは、私には少し矛盾しているように見える 2 つのことを示唆しています。

1) REST サービスは、リソース間のリンクとしてデータ関係を表す必要があります

2) クライアントからの「PUT」リクエストは、サーバー上で見られる表現と同じ形式の完全な表現でなければなりません。

私の観点からの問題は、リンク、およびおそらく典型的なリソースの他のかなりの数のプロパティが読み取り専用であるため、更新できないことです。サーバーは、クライアントがそれらを更新しようとしていると判断した場合は、エラーを返します。実際、JSON で表現された典型的なリソースを見ると、その大部分は、論理的に置き換えられない/置き換えられないデータです。例えば

{
 "link": { "rel":"self", "href":"http://example/project/12345" },
 "team": {
    "link": { "rel":"self", "href":"http://example/project/12345/team" },
    "title": "The project team"
  },
  "title": "The Big Project"
}

ここでは、せいぜい 2 つのタイトル テキストだけがこのリソースでクライアントに書き込み可能です (チーム メンバーシップはチーム リンクを介して変更できる場合があります)。

したがって、PUT にすべての「リンク」要素をそのまま正確に含めることを要求する必要があります。これは純粋に論理的で読み取り専用です (この例では、リソースがチームとして定義しているため、チームは再リンクできないことに注意してください)。プロジェクトの場合 - この場合は変更できますが、コンテナシップがより厳格な多くのリソース タイプには適用されません)。

多くのリンクを持つ REST でリソースを表すための標準パターンまたはアンチパターンはありますか? HATEOAS などの特定の REST バリアントを求められているわけではありませんが、可能であれば理論的な「正確さ」を目指す傾向があります。言い換えれば、「公式の」REST が、クライアントがリソース全体、リンク、およびすべてを PUT することを期待する場合、それはおそらく私が行うことです。

GET および PUT をサポートし、したがってこの問題に対処する必要がある現実世界の複雑な非リーフ REST リソースの例をいくつか挙げていただければ幸いです。検索すると、多くの意見が得られ、GET がいかにうまく機能するかを示す多くの例が得られます。. . しかし、これまでのところ、些細なリーフ リソース (つまり、おそらく自己参照を除いてリンクを含まないリソース) 以外への PUT を示す十分に文書化された例を見たことがありません。

4

2 に答える 2

3

基本的に、GET 要求は、定義された形式にシリアル化されたリソースと、そのリソースに関するメタデータ (これらが一緒になってリソースの表現を構成します) を返します。表現を PUT で戻す場合、メタデータを含める必要はなく、元の (または後続の) GET 要求と同じ形式である必要もありません。サーバーは、指定した表現に基づいてリソースを更新します。

HTML の例として、リソースに関するメタデータとリソース表現を提供する<head>and要素があります。<body>およびコンテンツ タイプはtext/htmlapplication/x-www-form-urlencodedリソース表現を 2 つの異なる形式で転送します。前者はメタデータあり、後者はなしです。リソースに POST した後にリソースを GET すると、形式のapplication/x-www-form-urlencodedデータを受け取ることは期待できません!

「RESTバリアント」の意味がわかりません。REST は 1 つだけです。他の HTTP ベースの API について言及している場合は、それらを REST と呼ばないでください。API スタイルの詳細については、 HTTP ベースの API の分類 を参照してください。

最後に、リーフ以外の PUT リクエストの例を尋ねます。私は2つのタイプを考えることができるので、あなたが葉以外のことを何を意味するのか正確にはわかりません:

  1. コレクション
  2. サブリソース

コレクション で入手できる車のカタログがあるとします/cars。すべての車を消去したい場合はDELETE /cars/1、 ... などを実行するか、空のボディまたは内容のない配列をDELETE /cars/2選択することができます。PUT /cars後者は明らかにはるかに効率的です。

サブリソース このテーマを続けて、/cars/1次のように表される車があるとしましょう。

{
  "model":"Model-T",
  "mfgr":"Ford",
  "colour":"black"
}

ここで、これらのフィールドへの URL からのアクセスを許可したい場合があり/cars/1/mfgrます。これで、URLは非リーフ リソースを表します。ただし、新しい表現を URL に PUT することにはまだ問題はありません。したがって、これにより、サブリソース URL の値も更新されます。Ford{"mfgr":"Ford"}/cars/1

最後に、JSON 経由でハイパーテキストを送信するためのHAL形式を確認することをお勧めします。

于 2013-01-23T12:13:47.323 に答える
1

メディア タイプで定義されているように、「完全な」表現を配置する必要があります。独自のメディア タイプを設計している場合は、変更可能にする部分と不変にする部分を仕様で定義する必要があります。たとえば、商事カタログ プロトコルでは、変更可能なデータを格納するための「本体」メンバーが定義されています。

一般に、body メンバーが存在する場合、プロセッサーは body 内に存在する値が潜在的に変更可能であることを期待する必要があり (たとえば、HTTP PUT または POST を介して)、body メンバーの外部の値は不変であることを期待する必要があります。つまり、(潜在的に) 挿入時に書き込み可能ですが、更新時には書き込み可能ではありません。サーバーはもちろん、リソースの任意の部分の可変性を許可または禁止するために自由です。しかし、「ボディ」メンバーの存在は、そのメンバーの内外でのデータの可変性に関する強力なヒントをもたらします。

これは標準ではありません (ただし、私にとっては非常に便利なので、1 つになりたいと思っています (ウィンク))。サーバーは、クライアントが送信する表現を自由に使用できることに注意してください。HTTP サーバーの最も強い要件は、クライアントの意図を実行しようとすることです (可能で許可されている場合)。それがどのように、どの程度行われるかは、特定のアプリケーションにとって本当に重要なことです。そのため、それに関する仕様はあまり見つかりません。

実際には、サーバーが表現のリンクやその他の不変部分を検証するのに役立つとは思いませんでした。それらは単に無視されます。これにより、クライアントはそのようなものを省略できると判断する可能性があります。繰り返しますが、実際には、それが問題になることはありませんでした。

于 2013-01-22T20:08:14.687 に答える