私は実用的なREST APIを設計していますが、既存のエンティティをコレクションに追加する最善の方法には行き詰っています。私のドメインモデルには、サイトのコレクションを持つプロジェクトが含まれています。これは厳密な多対多の関係であり、関係を明示的にモデル化するエンティティ(ProjectSiteなど)を作成する必要はありません。
私のAPIにより、消費者は既存のサイトをプロジェクトに追加できます。ハングアップしているのは、本当に必要なデータはProjectIdとSiteIdだけだということです。私の最初のアイデアは:
1. POST myapi/projects/{projectId}/sites/{siteId}
しかし、私も考えました
2. POST myapi/projects/{projectId}/sites
jSONコンテンツとして送信されたSiteエンティティを使用します。
オプション1はシンプルで機能しますが、適切とは言えません。また、このパターンに従わない他の関係があるため、APIに不整合が追加されます。
オプション2は気分が良くなりますが、次の2つの懸念につながります。
3番目のオプションは、関係を作成および削除するためだけの単純なエンドポイントを提供することです。このエンドポイントは、ProjectIdとSiteIdのみを含むJSONペイロードを予期します。
どう思いますか?
POSTは「追加」動詞であり、「処理」動詞でもあります。 PUTは(既知の識別子の)「作成/更新」動詞であり、完全なターゲットURIがわかっているため、ここではほぼ正しい選択のように見えます。 projectId
およびsiteId
はすでに存在しているため、新しいIDを生成するために「コレクションにPOSTする」必要はありません。
PUTの問題は、PUTしているリソースの表現である本文が必要であることです。ただし、ここでの目的は、サイトリソースを更新するのではなく、「プロジェクト/サイト」コレクションリソースに追加することです。
誰かが既存のサイトの完全なJSON表現をPUTした場合はどうなりますか?コレクションを更新する必要がありますandオブジェクトを更新しますか?あなたはそれをサポートすることができますが、それは意図ではないようです。あなたが言ったように、
私が本当に必要な唯一のデータはProjectIdとSiteIdです
むしろ、siteId
をコレクションにPOSTしてみて、POSTの「追加」および「プロセス」の性質に依存します。
POST myapi/projects/{projectId}/sites
{'id': '...'}
サイトコレクションリソースではなく、サイトリソースを変更しているので、これが目的のURIです。 POSTは、「追加/処理」して、そのIDの要素をプロジェクトのサイトコレクションに追加することを認識できます。
それでも、JSONを具体化し、IDを省略して、プロジェクトの新しいサイトを作成するための扉は開いたままです。 「IDなし」==「ゼロから作成」。しかし、コレクションURIがIDのみを取得した場合、何が発生する必要があるかは明らかです。
興味深い質問です。 :)
Patch
method をこのようなものに使用します。あなたがしたいことは、既存のプロジェクトを修正してサイトを追加することです。
このようなものはうまくいくでしょう
PATCH myapi/projects/{id}
site(s)エンティティをJSON/JSONArrayとしてリクエスト本文に含めます。
そうすることで、必要に応じて同じURLを使用してプロジェクトのさまざまな部分を変更できます。実装のコードは、リソースのこの部分的な変更を処理できるほどインテリジェントでなければなりません。