1. ホーム
  2. api

[解決済み] REST API - 一度のリクエストで一括作成・更新 [終了しました]。

2022-11-18 13:59:38

質問

2つのリソースがあるとします BinderDoc を意味する連想関係で DocBinder が独立して立つ。 Doc に属するかもしれないし、属さないかもしれない。 Binder そして Binder は空かもしれません。

のコレクションを送信できるような REST API を設計したいとします。 Doc s, を一回のリクエストで のような、以下のようなものです。

{
  "docs": [
    {"doc_number": 1, "binder": 1}, 
    {"doc_number": 5, "binder": 8},
    {"doc_number": 6, "binder": 3}
  ]
}

そして、各 doc に対して docs ,

  • もし doc が存在する場合、それを Binder
  • もし doc が存在しない場合は、それを作成し、それを

どのように実装すればいいのか、本当に困っています。

  • どの HTTP メソッドを使用するか?
  • どのようなレスポンスコードを返さなければならないか?
  • これはRESTの資格さえあるのか?
  • URIはどのように見えるでしょうか? /binders/docs ?
  • バルクリクエストを処理する際、いくつかのアイテムがエラーを発生させ、他のアイテムが通過した場合はどうなりますか。どのようなレスポンスコードを返さなければなりませんか?バルク操作はアトミックであるべきですか?

どのように解決するのですか?

一般的にPOSTやPATCHメソッドはこのような設計になっているので、POSTやPATCHメソッドで対応することができると思います。

  • を使用することで POST メソッド はリストリソース上で使用される場合、要素を追加するために一般的に使用されますが、このメソッドのためにいくつかのアクションをサポートすることもできます。この回答を参照してください。 RESTの方法でリソースコレクション全体を更新する . また、入力のための異なる表現形式をサポートすることができます(それらが配列または単一の要素に対応する場合)。

    場合、更新を記述するためにあなたのフォーマットを定義する必要はありません。

  • を使用することで PATCH メソッド を使うことも適切です。なぜなら、対応するリクエストは部分的な更新に対応するからです。RFC5789 によると ( https://www.rfc-editor.org/rfc/rfc5789 ):

    Hypertext Transfer Protocol (HTTP) を拡張するいくつかのアプリケーションは、リソースの部分的な変更を行う機能を必要とします。既存の HTTP PUT メソッドは、ドキュメントの完全な置き換えのみを許可しています。本提案は、既存の HTTP リソースを変更するために、新しい HTTP メソッド PATCH を追加します。

    では、部分的な更新を記述するためのフォーマットを定義する必要があります。

この場合、私は POSTPATCH は、各要素に対して行う操作を記述する必要がないので、かなり似ています。送信する表現の形式に依存すると言うことです。

の場合は PUT の場合は少し明確ではありません。実際、メソッドを使用する場合 PUT を使うときは、リスト全体を提供しなければなりません。実際のところ、リクエストで提供された表現は、リストリソースの1つを置き換えることになります。

リソースのパスに関して、2つのオプションがあります。

  • doc listのリソースパスを使用する

この場合、リクエストで提供する表現で、バインダーを持つdocのリンクを明示的に提供する必要があります。

以下はこのためのサンプルルートです。 /docs .

このようなアプローチの内容は、次のようになります。 POST :

[
    { "doc_number": 1, "binder": 4, (other fields in the case of creation) },
    { "doc_number": 2, "binder": 4, (other fields in the case of creation) },
    { "doc_number": 3, "binder": 5, (other fields in the case of creation) },
    (...)
]

  • binder要素のサブリソースパスの使用

さらに、ドキュメントとバインダーの間のリンクを記述するために、サブルートを活用することも検討できます。docとbinderの間の関連付けに関するヒントは、リクエストコンテンツ内で指定する必要はありません。

このためのサンプルルートは次のとおりです。 /binder/{binderId}/docs . この場合、docs のリストをメソッドで送信すると POST または PATCH はバインダーにドキュメントを添付する際に識別子 binderId でバインダーに追加します。

このようなアプローチのコンテンツは、メソッド POST :

[
    { "doc_number": 1, (other fields in the case of creation) },
    { "doc_number": 2, (other fields in the case of creation) },
    { "doc_number": 3, (other fields in the case of creation) },
    (...)
]

レスポンスについては、どのレベルのレスポンスを返すか、どのようなエラーを返すかを定義するのは、あなた次第です。私は、ステータス・レベル(グローバル・レベル)とペイロード・レベル(より薄いレベル)の2つのレベルがあると見ています。また、リクエストに対応するすべての挿入/更新がアトミックでなければならないかどうかの定義も、あなた次第です。

  • アトミック

この場合、HTTPのステータスを活用することができます。すべてがうまくいった場合、ステータス 200 . そうでない場合は、次のような別のステータスが 400 のような別のステータスが表示されます。

  • 非原子力

この場合、ステータス 200 が返され、何が行われたか、最終的にどこでエラーが発生したかを記述するのは、レスポンス表現次第です。ElasticSearchのREST APIには、一括更新のためのエンドポイントが用意されています。これを使えば、このレベルでも何かアイデアが浮かぶかもしれません。 http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/bulk.html .

  • 非同期

提供されたデータを処理するために、非同期処理を実装することも可能です。この場合、HTTPステータスの返り値は 202 . クライアントは何が起こるか見るために、追加のリソースを引き出す必要があります。

最後に、OData仕様がエンティティ間の関係に関する問題に対処していることに注目したいと思います。 ナビゲーションリンク . おそらく、あなたはこれを見ていることができます;-)

次のリンクも参考になります。 https://templth.wordpress.com/2014/12/15/designing-a-web-api/ .

お役に立てれば幸いです。 Thierry