web-dev-qa-db-ja.com

RESTful APIでオブジェクト階層をどのように扱う必要がありますか?

現在、既存のPHPアプリケーション用のAPIを設計しています。この目的のために、賢明なアーキテクチャアプローチとしてRESTを調査しています。

私は主要な概念を合理的に把握していると思いますが、オブジェクト階層とRESTに取り組んできた人を見つけるのに苦労しています。

ここに問題があります...

[アプリケーション]ビジネスオブジェクト階層には次のものがあります。

Users 
 L which have one-to-many Channel objects
 L which have one-to-many Member objects

アプリケーション自体では、遅延ロードアプローチを使用して、必要に応じてこれらのオブジェクトの配列をUserオブジェクトに設定します。 OO用語これはオブジェクトの集約ですが、私はさまざまな命名の不一致を見てきましたが、正確な命名規則についての戦争を始める気にはなりません。

とりあえず、アプリケーションのニーズに応じてデータを取り込む場合と取り込まない場合のある疎結合オブジェクトがあることを考えてください。

RESTの観点から、アプローチがどうあるべきかを確認しようとしています。現在の考え方は次のとおりです(とりあえずGETを検討してください):

オプション1-オブジェクトを完全に設定します:

GET api.example.com/user/{user_id}

Userオブジェクト(リソース)を読み取り、すべての可能なChannelおよびMemberオブジェクトが事前にロードおよびエンコードされた(JSONまたはXML)Userオブジェクトを返します。

長所:オブジェクトの数を減らし、オブジェクト階層のトラバースは不要
CONS:オブジェクトは完全に入力する必要があります(高価)

オプション2-プライマリオブジェクトを作成し、他のオブジェクトリソースへのリンクを含める:

GET api.example.com/user/{user_id}

ユーザーオブジェクト(リソース)を読み取り、ユーザーオブジェクトのユーザーデータと2つのリストを返します。

各リストは、適切な(サブ)リソース、つまり.

api.example.com/channel/{channel_id}
api.example.com/member/{member_id}

これは、ハイパーメディアの意味に(または正確に)近いと思います-クライアントは、必要に応じて他のリソースを取得できます(賢明にタグ付けする限り)。

長所:クライアントは、部下をロードするか、そうでなければ、REST resources
CONS:セカンダリリソースを取得するにはさらに旅行が必要です

オプション3-再帰的な取得を有効にする

GET api.example.com/user/{user_id}

Userオブジェクトを読み、サブオブジェクトのリストへのリンクを含めます。

api.example.com/user/{user_id}/channels
api.example.com/user/{user_id}/members

/ channels呼び出しは、次の形式でチャネルリソースのリストを返します(上記を参照)。

api.example.com/channel/{channel_id}

長所:プライマリリソースはサブノードを取得するためにどこに行くかを公開しますが、それらが何であるか(よりRESTful?)、サブグループを前もって取得する必要はありません応答より多くのサービスのような。
CONS:オブジェクトを完全に取り込むために3つの呼び出しが必要になりました

オプション4-RESTのオブジェクト設計を(再)考慮する

[既存の]アプリケーションオブジェクト階層を再利用し、それをREST-またはさらに直接、APIインターフェイスを提供する)に適用しようとしています。

おそらくRESTオブジェクト階層は異なる必要があります。または、新しいRESTfulの考え方が既存のオブジェクト設計の制限を明らかにしている可能性があります。

上記に関するご意見を歓迎します。

どうもありがとう

ポール

68
paulkmoore

これらを組み合わせない理由はありません。

  • api.example.com/user/{user_id} –ユーザー表現を返します
  • api.example.com/channel/{channel_id} –チャネル表現を返します
  • api.example.com/user/{user_id}/channels –チャネル表現のリストを返します
  • api.example.com/user/{user_id}/channel_list –チャンネルIDのリスト(または上記のリンクを使用した完全な表現へのリンク)を返します

疑問がある場合は、「API」を気にせずにデータを人間のユーザーに表示する方法を考えてください。ユーザーは両方のインデックスページ({user_id}/channel_list)およびフルビュー({user_id}/channels)。

それができたら、表現形式としてHTMLの代わりに(またはそれに加えて)JSONをサポートするだけで、RESTが得られます。

39
Pi Delport

私ができる最善のアドバイスは、REST apiをオブジェクトを公開するものとして考えないようにすることです。作成するリソースは、必要なユースケースをサポートする必要があります。 3つのオプション:

api.example.com/completeuser/{id}
api.example.com/linkeduser/{id}
api.example.com/lightweightuser/{id}

明らかに私の名前は少し間抜けですが、実際にあなたがそれらを何と呼ぶか​​は問題ではありません。 REST apiを使用して、特定の使用シナリオに最も論理的な方法でデータを表示するという考え方です。複数のシナリオがある場合、必要に応じて複数のリソースを作成します。私のリソースは、ビジネスエンティティではなくUIモデルに似ています。

25
Darrel Miller

Restful Obects をお勧めします。これは、ドメインモデルの落ち着いた雰囲気を公開するための標準です

Restful Objectsの考え方は、ドメインオブジェクトモデルに標準の汎用RESTfulインターフェイスを提供し、JSONを使用して構造の表現を公開し、HTTP GET、POST、PUT、DELETEを使用してドメインオブジェクトインスタンスとの対話を可能にすることです。

標準によると、URIは次のようになります。

  • api.example.com/object/user/31
  • api.example.com/object/user/31/properties/username
  • api.example.com/object/user/31/collections/channels
  • api.example.com/object/user/31/collections/members
  • api.example.com/object/user/31/actions/someFunction
  • api.example.com/object/user/31/actions/someFunction/invoke

他のリソースもあります

  • api.example.com/services
  • api.example.com/domain-types

仕様では、いくつかの主要な表現を定義しています。

  • オブジェクト(ドメインオブジェクトまたはサービスを表します)
  • リスト(他のオブジェクトへのリンクの)
  • 財産
  • コレクション
  • アクション
  • アクション結果(通常、オブジェクトまたはリストのいずれか、またはフィードバックメッセージのみを含む)
  • また、自宅やユーザーなどの少数の副次的表現

これは、表現が完全に自己記述的であり、必要に応じて一般的な視聴者が実装される可能性を開くことがわかるため、興味深いものです。

または、特注のアプリケーションで表現を直接使用することもできます。

9
Yasir Hantoush

ここに多くの時間の検索からの私の結論とレスポンダーからの入力があります:

事実上マルチパートオブジェクトであるオブジェクトがある場合、それを単一のリソースとして扱う必要があります。したがって、オブジェクトを取得すると、すべての部下が存在するはずです。これは、リソースがキャッシュ可能であるために必要です。オブジェクトを部分的にロードする(およびETagスタンプを提供する)と、他のリクエスターが完全なオブジェクトを予期したときに部分的なオブジェクトを受け取ることがあります。 結論-オブジェクトがリソースとして利用可能になっている場合、オブジェクトは完全に読み込まれている必要があります。

関連付けられたオブジェクトの関係は、他の(プライマリ)リソースへのリンクとして利用可能にする必要があります。このように、オブジェクトはAPIをトラバースすることで検出可能です

また、メインアプリケーションサイトに意味のあるオブジェクト階層は、RESTfulな方法で行動する必要があるものとは思われないかもしれませんが、既存の階層の問題を明らかにする可能性が高くなります。とはいえ、APIには以前に想定されていたよりも特殊なユースケースが必要になる場合があり、特殊なリソースが必要になる場合があります。

誰かを助けることを願っています

6
paulkmoore