web-dev-qa-db-ja.com

REST-Uniform Interfaceの正確な意味は?

ウィキペディアには:

均一なインターフェース

統一されたインターフェイスの制約は、任意のREST service。[14]の設計の基本です。統一されたインターフェイスは、アーキテクチャを簡素化および分離し、各部分が独立して進化できるようにします。次のとおりです。

リソースの特定

個々のリソースは、たとえばWebベースのREST=システムのURIを使用して、リクエストで識別されます。リソース自体は、クライアントに返される表現と概念的に分離されます。たとえば、サーバーはデータベースからのデータはHTML、XML、またはJSONであり、いずれもサーバーの内部表現ではなく、いずれにせよ同じリソースです。

これらの表現によるリソースの操作

クライアントは、添付されたメタデータを含むリソースの表現を保持している場合、リソースを変更または削除するのに十分な情報を持っています。

自己記述メッセージ

各メッセージには、メッセージの処理方法を説明するのに十分な情報が含まれています。たとえば、呼び出すパーサーは、インターネットメディアタイプ(以前はMIMEタイプとして知られていました)で指定できます。応答は、キャッシュ可能性も明示的に示します。

アプリケーション状態のエンジンとしてのハイパーメディア(A.K.A. HATEOAS)

クライアントは、サーバー(たとえば、ハイパーテキスト内のハイパーリンク)によってハイパーメディア内で動的に識別されるアクションを介してのみ状態遷移を行います。アプリケーションへの単純な固定エントリポイントを除いて、クライアントは、サーバーから以前に受信した表現で説明されているもの以外の特定のリソースに対して特定のアクションが利用可能であると想定しません。

私は主題についての講義を聞いています、そして、講師は言いました:

「誰かが私たちのAPIに近づいたときに、顧客オブジェクトを取得でき、注文オブジェクトがあることがわかっている場合、顧客オブジェクトを取得したのと同じパターンで注文オブジェクトを取得できるはずです。これらのURIはお互いのように見えます。」

これは私を間違っているように感じます。URIがどのように見えるか、またはURIが使用される方法であるため一貫性があるということではありません(リソースを識別し、表現、自己記述的なメッセージ、およびハテアを通じてリソースを操作します)。

これがUniform Interfaceの意味するところではないと思います。正確にはどういう意味ですか?

24
richard

インターフェイスを使用して、依存関係の実装からクラスを分離することは、かなり古い概念です。私はあなたがそれを聞いていないことに驚いています...

RESTと同じ概念を使用して、クライアントをRESTサービスの実装から切り離します。このようなインターフェースを定義するには、これは、RESTサービスのインターネットサイズのネットワークが必要な場合、相互に理解させるための標準などのグローバルな概念を適用する必要があるためです。

  • リソースの識別-URI(IRI)標準を使用してリソースを識別します。この場合、リソースはWebドキュメントです。

  • これらの表現によるリソースの操作-通信を記述するためにHTTP標準を使用します。たとえば、GETは、URIで識別されたリソースに関するデータを取得することを意味します。 HTTPメソッドとURIを使用して操作を記述することができます。

  • 自己記述メッセージ-標準のMIMEタイプと(標準)RDF vocabsを使用してメッセージを自己記述的にします。したがって、クライアントはセマンティクスをチェックすることでデータを見つけることができます。サービスが使用するアプリケーション固有のデータ構造を知るため。

  • アプリケーション状態のエンジンとしてのハイパーメディア(A.K.A. HATEOAS)-ハイパーリンクと場合によってはURIテンプレートを使用して、クライアントをアプリケーション固有のURI構造から分離します。これらのハイパーリンクにセマンティクスなどの注釈を付けることができます。 IANAは関係をリンクするため、クライアントはそれらの意味を理解します。

35
inf3rno

"Uniform interface"制約は、ReSTfulアーキテクチャが従うべきであり、実際にはサーバーの応答が利用可能なアクションとリソースをアナウンスすることを意味します。

つまり、リソースを照会すると、クライアントは事前に知らなくても他のアクションやリソースを要求できるようになります。

JSON-API specは良い例を提供します:

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        }
      }
    },
    "links": {
      "self": "http://example.com/articles/1"
    }
  }]
}

この単一の応答を分析するだけで、クライアントは次のことを知ります。

  1. 彼が照会していたもの(記事)
  2. 構造化された記事(id、タイトル、著者、コメント)はどうですか
  3. 関連オブジェクト(つまり、作成者、コメントリスト)を取得する方法
  4. より多くの記事があること(10、現在の応答の長さとページネーションのリンクに基づいて)

これがお役に立てば幸いです。
このトピックに熱心な人には、 Thomas Fieldingの論文 !を読むことを強くお勧めします。

4

あなたの質問はいくぶん広範であり、あなたはあなたが持っている定義の言い換えを求めているようです。例を探しているのか、具体的に述べられていることを理解していないのか。

私は次のことに同意します:

これらのURIはお互いのように見えます

根本的に間違っています。 Uniformインターフェースの制約を満たすために、URIが互いに似ている必要はありません。存在する必要があるのは、リソースを識別するURIを発見するための統一された方法です。この統一された方法は、各メッセージタイプに固有であり、合意された形式が必要です。たとえば、HTMLでは、1つのドキュメントリソースが単純なタグを介して別のリソースにリンクします。

<a href="URI of related resource" rel="defined relationship">fallback relationship</a>

HTTPサーバーは、htmlをtext/htmlリソースタイプとして返​​します。これは、ブラウザーが解析方法について合意しているものです。アンカータグは、関連リソースの一意の識別子を持つハイパーメディアコントロール(HATEOAS)です。

カバーされなかった唯一のポイントは操作でした。 HTMLには、これに関するもう1つの素晴らしい例、formタグがあります。

<form action="URI" method="verb">
  <input name=""></input>
</form>

この場合も、ブラウザはこのメタ情報を解釈して、URIで動作するリソースの表現を定義する方法を知っています。残念ながらHTMLでは、GETとPOST verbs ...

より一般的には、JOSNベースのサービスでは、Personリソースを取得するときに、その表現を簡単に操作してから、正規のURLにPUTまたはPATCHで戻すことが簡単です。リソースを変更するために、リソースに関する既存の知識は必要ありません。クライアントコードを記述するとき、実際に形状を消費する前に形状を知る必要があるという考えですべてがラップされます...しかし、それは本当にパーサーを効率的かつ簡単にするためです。リソースの各部分のセマンティックな意味を分析するパーサーを作成し、修正の意図を解釈することで修正できます。 IE:10歳以上の人に年齢を探してリソースを解析し、年齢を特定し、その値に10年を加算してから、そのリソースをサーバーに送り返すコマンド。年齢が$ .ageのJSONパスにあることを期待するコードを持つ方が簡単ですか?絶対に...しかし、それは特に必要ではありません。

3
Chris DaMour

わかりました。それが何を意味するか理解できたと思います。

フィールディングの論文から:

RESTアーキテクチャスタイルを他のネットワークベースのスタイルと区別する中心的な機能は、コンポーネント間の統一されたインターフェイスに重点を置いていることです(図5-6)。コンポーネントインターフェイスにより、システムアーキテクチャ全体が簡素化され、相互作用の可視性が向上します。

彼は、コンポーネント間のインターフェースは同じでなければならない、と言っています。すなわち。クライアントとサーバー、およびすべての仲介者の間で、すべてがコンポーネントです。

2
richard