web-dev-qa-db-ja.com

REST API-REST

そのため、RESTの境界の外にあるように見えるREST APIで何かをしなければならないことがよくあります。この特定のインスタンスでは、メンバーが適格かどうかをチェックするエンドポイントが必要です無料のトレーニングかどうか。

この情報を読み取りエンドポイントに追加することもできますが、それは、読み取り呼び出しのたびにその情報が返されることを意味します。今回は問題ありませんが、100のチェックがあり、特定の時間にのみ必要な100のフィールドを返すとどうなりますか?肥大化するだけです。

/ member/{id}/eligibleForFreeTrainingのようなエンドポイントを作成してもかまいません。trueまたはfalseを返すだけですが、それはCRUDまたはRESTではありません。

これらの種類の呼び出しはREST'ish APIにどこに適合しますか?

3
Bill Garrison

リソースに追加します。これらの「この特別なプロモーションが適用されますか」という質問の多くでリソースが膨大になる場合は、それらを関連するリソースに分割してください。たとえば、GET /member/{id}/promotionsです。 URL構造に依存するのではなく、 Link Headers を使用して、プロモーションが配置されている/member/{id}リソースを介して通信するか、すべてのプロモーションを最上位に配置することもできます/promotionsメンバーでフィルターできるコレクション(例:/promotions?member=/member/{id})。

一般に、特定のコンテキストでのみ役立つ関連する追加情報がある場合は、関係者が最初のリソースから到達できる個別のリソースとしてそれを表現します。さらに、「checkXする必要がある」とは考えず、「resourceXのチェック結果を表します。 /member/{id}/promotionsリソースは、特定のメンバーに適用されるプロモーションを確認し、それらをあなたに提供するサーバーを表します。サーバーはチェックとロジックを行います。クライアントはリソースを要求するだけです。

7
Jack

/ member/{id}/eligibleForFreeTrainingのようなエンドポイントを作成してもかまいません。trueまたはfalseを返すだけですが、それはCRUDまたはRESTではありません。

RESTはCRUDではありません。

RESTは、Representational State Transferです。クライアントとサーバーの間でリソースの状態を転送しています。クライアントまたはサーバーがこれらの表現をどのように処理するかは、クライアント次第です。 REST通信レベルでは、プロトコルは、クライアントまたはサーバーが取得した表現に対してクライアントまたはサーバーが実行するアクションについては関係ありません。HTTPの問題ではありません。

リソースはそれ自体が抽象化レイヤーであり、サーバーの内部データモデルにマップする必要はありません。また、HTTP動詞(GET、POST、PUT、DELETEなど)は、データモデルのCRUDコマンドにマップする必要もありません。 。サーバーでは、1つのデータベーステーブルと20のリソースがクライアントに公開されている場合があります。または、クライアントがサーバーに表現をPUTすると、サーバーはそれをデータベース、20のデータベース、フラットファイル、メモリに格納します。 HTTPは関係ありません。

RailsのようなWebフレームワークを使用している可能性がありますが、基本的にこの点は理解できませんが、フレームワークがそのように実行しているからといって、これが正しい方法であるとは限りません。必要に応じて、HTTPインターフェイスで公開されるリソースをいくつでも持つことができます。

今回は問題ありませんが、100のチェックがあり、特定の時間にのみ必要な100のフィールドを返すとどうなりますか?肥大化するだけです。

それを気にする十分な理由がない限り(リソースのサイズがメガバイトなど)、それについて心配する必要はありません。その特定のユースケース用のURLスキームを構築するのは時期尚早の最適化です。実用的な観点から見ると、メンバーリソースに100フィールドのうち5つのフィールドがある場合、データの転送にはほとんど違いがありません。

これがリソースのURLであると言う方がはるかに簡単です。好きなときに使用してください。クライアントはメンバーの名前だけを必要とする場合があります。会員の年齢だけでいいかもしれません。トレーニングに無料かどうかを確認したいだけのメンバーの名前や年齢は気にしないかもしれません。

クライアントがデータを必要とする理由の各ユースケースのURLエンドポイントを構築しようとすると、システムの複雑さが大幅に高まります。単にクライアントに「ここにリソースがあります」と言って、クライアントにそのリソースから必要なものを決定させるのははるかに簡単です。

2
Cormac Mulhall

/ member/{id}/eligibleForFreeTrainingのようなエンドポイントを作成してもかまいません。trueまたはfalseを返すだけですが、それはCRUDまたはRESTではありません。

これには前例があります。例えば: https://developer.github.com/v3/gists/#check-if-a-Gist-is-starred

この情報を読み取りエンドポイントに追加することもできますが、それは、読み取り呼び出しのたびにその情報が返されることを意味します。今回は問題ありませんが、100のチェックがあり、特定の時間にのみ必要な100のフィールドを返すとどうなりますか?肥大化するだけです。

1つの答えは、詳細のレベルが異なる複数の表現を持つことができるということです。そのためのRESTfulな方法は、さまざまな表現を記述するさまざまなメディアタイプを用意することです。

たとえば、 Sun CloudのAPI は、異なる ベンダーメディアタイプ で識別されるさまざまなJSON表現を定義します。

複数のメディアタイプ表現を持つリソースを実装することは常に許可されており、「ルール」には、同じメディアタイプサフィックスを持つ複数の表現を持つことを妨げるものはありません。

リソースのクライアント要求は適切なメディアタイプを指定し、サーバーは利用可能な場合はそれを提供します。

利用可能なメディアタイプについて通信するRESTfulな方法は、ハイパーメディアコントロールを介してそれらの利用可能性を通知することです。つまり、リソースの「標準」メディアタイプを指定するリンクをクライアントに提供することに加えて、他の状況で使用できる代替リンクをクライアントに提供します。

[〜#〜] edit [〜#〜]許可されますが、必ずしも推奨されるわけではありません。

リソースの所有者は、フォーマット間の唯一の違いが機械的な性質である場合にのみ、リダイレクトなしで真のコンテンツネゴシエーションを使用することを推奨します。

- フィールディング、2006

ジャックがコメントで述べたように、サポートしたいさまざまな表現に異なる論理リソースを使用することをお勧めします。

つまり、RESTアプリケーション(つまり、APIがプロトコルを提供している場合)では、クライアントに状態を通知する必要がないことを指摘する価値があるでしょう。フラグ。ただし、代わりにフラグの状態を使用して、クライアントに送信するリソースの表現に他のリソースへのリンクを含めるかどうかを決定します。

たとえば、資格のあるメンバーへの「無料トレーニングに登録」リンクを含め、メンバーが資格がない場合は、クライアントがクライアントに提供されたリンクのみを操作することを理解して、リンクを保留することを意味します。アプリケーション状態の一部として。

1
VoiceOfUnreason