API - 複数のリクエストとユーザーの役割の分離
-
22-12-2019 - |
質問
私は単一ページのアプリケーションのフロントエンドに取り組んでおり、多数の学生をリストする必要があります。各生徒は特定のことに執着しています user_id
これは、実行時にすべてのユーザー ロール (スーパー管理者、管理者、教授、学生) に対して API が返すものです。 GET /students
:
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
私は現在スーパー管理者の役割に取り組んでおり、各生徒からの追加データが必要です (subscription_type
)、でのみ利用可能です。 GET /users/:id
したがって、ページに 20 ~ 30 人の学生をリストする場合、 GET /students/
, を得るために、 subscription_type
, また、生徒ごとに 1 つずつ、20 ~ 30 件の追加のリクエストを行う必要があります。
このことについて API 担当者に相談したところ、余分なデータを students
「これは RESTful な方法ではありません」、「応答時間がさらに遅くなります」、「30 個の追加リクエストは大きな塊よりも軽い」です。
API に関する作業については何も知らないので、何とも言えませんが、1 ページの読み込みで 30 件のリクエストがバカバカしいと考えるのは気が狂っているのでしょうか?
それで、次は何でしょうか?先に進んで追加のリクエストを実行しますか?ユーザーの役割ごとに応答を分けて、各役割に必要なものだけを含めるべきでしょうか?とは何ですか 正しい方法 これを処理するのは?
解決
厳密に言えば、API 担当者は正しいですが、RESTful の福音に厳密に従うと、純粋主義的な実装によって生じる 1+N 問題のような非効率につながる可能性があります。RESTful 設計の重要な概念は、リソースをドメイン オブジェクトに直接マップする必要がないということです。リソースを設計するときは、使用シナリオを検討する必要があります。スーパー管理者のシナリオでは、クライアントが次のコレクションをリクエストしたときのように聞こえます。 students
また、通常または常に、からのデータも必要とします。 users
, 、 具体的には subscription_type
. 。オブジェクト モデルは明らかに正規化されているはずですが、リソースがそうである必要がある、または常にそうである必要があるというわけではありません。
同様のシナリオをより効率的にするために使用したいくつかの異なるパターンがあります。どちらが適用されるかは、クライアントによるリソースの消費方法によって異なります。
複合リソース
これは、2 つ以上のドメイン オブジェクトのすべてまたは一部の組み合わせです (例: student
そして user
) を単一のリソースにまとめます。
ずっと students
おそらくも users
, に応じて、ユーザー データのすべてまたは一部を学生リソースに含めることができます。
GET /students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
subscription_type: "foo"
}
関連リソース
(別の応答と同様) これは、クライアントが関連リソースを応答に含めたいことを示すことができる手法です。これは、ドメイン モデルの「has a」型関係で特に役立ちます。これにより、クライアントは基本的に次のことを行うことができます 遅延ロード または 熱心なロード リソース。
GET /students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
GET /students?include_user=true
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
user:
{
id: 238
subscription_type: "foo"
...
}
}
他のヒント
ここでは2つの問題があります。 1つは、インデックスコール(/生徒)の各ユーザーに対して返されるデータであり、もう1つは特定のユーザーがどのデータを公開できるかを決定する必要がある認証プロセスです。
データの問題については、従うべき具体的な規則があるとは思わない。それはあなたのアプリの要求に完全に依存します。 subscription_typeフィールドが通常不要な場合は、クエリパラメータ( 'include_extra_data= 1')を渡すことを検討して、特定の要求に必要なことを示します。
許可の問題に関して - これはあなたの要求を求めるあなたのデータから完全に切断されるべきです。サーバは、ユーザIDに従ってどのデータがユーザに表示されるかを判断することができなければならない。 ( cancan gem] [1] を解決策)。
だから、2つの問題を組み合わせると、任意の種類のユーザーが 'include_extra_data'フラグの有無にかかわらず、 '/ Segulys'の要求を行うことができるはずです。サーバーが追加のデータを表示するようにユーザーがユーザーが見つけられた場合は、2つのオプションのいずれかを選択できます - ユーザーが表示することを許可されているデータのみを返す、または「401不正な」レスポンスを返します。
両方の方法は有効であり、クライアントアプリに対する応答に対処する方法に影響を与えます。 (私は、個人的には、その後半をより説明的である)。
これが役に立つことを願っています:)