1. ホーム
  2. class

RESTful APIでオブジェクトの階層をどのように扱えばよいですか?

2023-09-25 23:58:51

質問

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

私は重要な概念を合理的に把握していると信じていますが、オブジェクト階層とRESTに取り組んだことのある人を見つけるのに苦労しています。

ここで問題です...

アプリケーション]ビジネスオブジェクトの階層には

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

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

今のところ、私がアプリケーションの必要性に応じて入力するかもしれない/しないかもしれない、いくつかの疎結合オブジェクトを持っていると考えてください。

RESTの観点から、私はどのようなアプローチであるべきかを確認しようとしています。 以下は私の現在の考えです (当面は GET のみを考慮)。

オプション 1 - オブジェクトに完全に入力する。

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

ユーザーオブジェクト(リソース)を読み込み、可能な限りのチャンネルとメンバーオブジェクトをあらかじめロードしてエンコードした状態でユーザーオブジェクトを返す(JSONまたはXML)。

長所:オブジェクトの数を減らすことができる、オブジェクト階層のトラバーサルが必要ない

CONS: オブジェクトに完全に値を入れる必要がある (コストがかかる)

オプション2 - 主オブジェクトに値を入れ、他のオブジェクトリソースへのリンクを含む。

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

Userオブジェクト(リソース)を読み込み、Userオブジェクト Userデータを投入したものと2つのリストを返す。

各リストは適切な(サブ)リソース、すなわち

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

これはハイパーメディアの意味合いに近い(あるいはまさに)ものだと思います。クライアントは望むなら他のリソースを得ることができます(私が分別あるタグ付けをする限り)。

PROS: クライアントは下位のものをロードするかどうかを選択できる、RESTリソースとしてオブジェクトをよりよく分離することができる

短所:下位リソースを取得するためにさらに移動が必要

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

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

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

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

を呼び出すと、チャンネルリソースのリストが (上記のような) 形式で返されます。

api.example.com/channel/{channel_id}
    

長所: 主なリソースは、下位のものを取得するためにどこに行くかを公開しますが、下位のものが何かは公開しません(よりRESTfulになるか)、前もって下位のものを取得する必要はありません、下位リスト生成器(/channelsと/members)は、レスポンスをよりサービス的にするインターフェース(メソッド的)を提供します。

欠点:オブジェクトに完全に情報を入力するために3回の呼び出しが必要

選択肢4 - RESTのためのオブジェクトの設計を(再)検討する

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

おそらくRESTオブジェクト階層は異なるべきで、あるいは新しいRESTfulな考え方が既存のオブジェクト設計の制限を露呈しているのでしょう。

上記についてどんな考えでも歓迎します。

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

これを組み合わせない手はない。

  • 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の出来上がりです。