そのREST APIは本当にRPCですか?ロイ・フィールディングはそう考えるようです


99

RESTについて私が知っていると思っていたものの多くは明らかに間違っている-そして私は一人ではない。この質問には長い導入がありますが、情報が少しばらばらなので、必要なようです。このトピックにすでに精通している場合は、実際の質問が最後に来ます。

Roy FieldingのREST APIの最初の段落はハイパーテキスト駆動である必要があることから、彼の仕事が広く誤解されていると彼が信じていることは明らかです。

HTTPベースのインターフェースをREST APIと呼ぶ人々の数に不満を感じています。今日の例はSocialSite REST APIです。それがRPCです。それはRPCを叫びます。ディスプレイには非常に多くのカップリングがあるため、Xレーティングを指定する必要があります。

フィールディングでは、REST APIのいくつかの属性をリストします。それらのいくつかは、SOや他のフォーラムでの一般的な慣行と一般的なアドバイスの両方に反対するようです。例えば:

  • REST APIは、最初のURI(ブックマーク)と、対象とするオーディエンスに適した標準化されたメディアタイプのセット(APIを使用する可能性のあるすべてのクライアントによって理解されることが期待される)以外の事前知識なしで入力する必要があります。...

  • REST APIは、固定リソース名または階層(クライアントとサーバーの明らかな結合)を定義してはなりません。...

  • REST APIは、リソースの表現とアプリケーションの状態の駆動に使用されるメディアタイプの定義、または既存の標準メディアタイプの拡張リレーション名やハイパーテキスト対応マークアップの定義に、ほとんどすべての記述的努力を費やすべきです。...

「ハイパーテキスト」のアイデアは中心的な役割を果たします。URI構造やHTTP動詞の意味よりもはるかに重要です。「ハイパーテキスト」は、コメントの1つで定義されています。

私が[フィールディング]とハイパーテキストを言うとき、それは情報とコントロールの同時の提示を意味し、情報はユーザー(またはオートマトン)が選択肢を取得してアクションを選択するためのアフォーダンスになるようにします。ハイパーメディアは、メディアストリーム内に一時的なアンカーを含めるというテキストの意味を拡張したものです。ほとんどの研究者は区別を落としました。

ブラウザでハイパーテキストをHTMLにする必要はありません。マシンは、データ形式と関係タイプを理解すると、リンクをたどることができます。

私はこの時点で推測していますが、上記の最初の2つのポイントは、次のようなFooリソースのAPIドキュメントは、クライアントとサーバー間の密結合につながり、RESTfulシステムには場所がないことを示唆しているようです。

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

代わりに、エージェントは、/ foosに対してGETリクエストを発行するなどして、すべてのFoosのURIを検出するように強制する必要があります。(これらのURIは、上記のパターンに従うことが判明する可能性がありますが、それはポイントの横にあります。)応答は、各アイテムへのアクセス方法とそれで実行できることを伝えることができるメディアタイプを使用し、上記の3番目のポイントをもたらします。 。このため、APIドキュメントでは、応答に含まれるハイパーテキストを解釈する方法の説明に重点を置く必要があります。

さらに、FooリソースへのURIが要求されるたびに、応答には、エージェントがURIを介して関連リソースや親リソースにアクセスしたり、作成後にアクションを実行したりするなどの方法を発見するために必要なすべての情報が含まれます/リソースの削除。

システム全体の鍵は、応答がメディアタイプに含まれるハイパーテキストで構成され、それ自体がエージェントに処理のオプションを伝えることです。これは、ブラウザが人間に対して機能する方法と同じです。

しかし、これは現時点での私の推測です。

フィールディングはフォローアップを投稿し、彼の議論はあまりに抽象的で、例が不足しており、専門用語が豊富であるという批判に応えました。

他のものは、私が書いたものをより直接的に、または今日のいくつかの実際的な懸念に適用できる方法で解読しようとします。次のトピックに取り組んでいる、会議の準備をしている、別の標準を書いている、遠く離れた場所に旅行している、または給料を稼いだと感じさせるちょっとしたことをしているので忙しくないので、おそらくそうしません。

それで、実用的な考え方を持つRESTエキスパートへの2つの簡単な質問:Fieldingが言っていることをどのように解釈し、REST APIを文書化/実装するときにそれをどのように実践しますか?

編集:この質問は、話している内容の名前がないと、何かを学ぶのがどれほど難しいかを示す例です。この場合の名前は、「アプリケーション状態のエンジンとしてのハイパーメディア」(HATEOAS)です。


26
ジョン、リッチは彼が持っていた考え方の変化を説明しているだけです。それについて主観的または議論的なことは何もありません。オープンに保つための投票-これは、私がSOで見た 'rest'とタグ付けされたより良い質問の1つです。
キースガガン、

4
キースは、「考え方の変化を説明する」ことは、SOではなくブログで行うべきことです。
ジョンサンダース、

13
彼は考え方の変化を説明しているのではなく、彼の理解が正確であるかどうかを尋ねています。
aehlke 2009

4
素晴らしい要約。ほとんどの回答よりも、この質問から多くを学びました。
Martin Konecny、2014

回答:


21

あなたの説明はほとんどそれをカバーしていると思います。URIは不透明な識別子であり、ほとんどの場合、ユーザーエージェントがアプリにアクセスするために使用するブックマークURIを超えて通信することはできません。

文書化に関しては、この質問はかなり何度も行われています。メディアタイプとそれに含まれるハイパーリンクコントロール(リンクとフォーム)、および必要に応じて相互作用モデル(AtomPubを参照)を文書化します。

URIやそれらの作成方法を文書化すると、間違っていることになります。


これはまだ本当ですか?これらのURIを意図的に応答の一部として作成したIonspecなどのAPI応答仕様があります。
Sean Pianka

はい。彼らは持っています。その時点で、これらのドキュメント化されたURIがアプリケーションへのエントリポイントであり、それがとどまることが保証されている(それらのいくつかは珍しくなく、かなり有用ではない)か、または人々がコード生成を望んでいるため、それらが仕様をコードに直接挿入することで、サーバーがクライアントにどのように実行できるかを通知するのを防ぎます。その契約のためにクライアントが知っているとクライアントが思った場合、あなたはハイパーメディアではなく、今日のopenapi soapモデルに入り、18年前に遭遇したのと同じ問題を抱えています。
SerialSeb

確かに、過去11年間に多くのAPIドキュメント言語が登場しましたが、基本は変わっていません。これらのリンクを発見すること、または少なくともURIテンプレートを発見することの価値は、それらを動的に使用できる再利用可能な汎用クライアントコードを構築し、サーバー側の多くの実装で同じクライアントコードを再利用できるようにすることだと思います。URIの埋め込みにより、このようなシナリオはさらに困難になりますが、これらの形式を使用すると、生成されたクライアントをこれらの仕様から密結合する傾向があるため、その機能はすでに失われています。
SerialSeb

8

あなたの解釈は私には正しいようです。フィールディングの制約は実際に適用できると思います。

RESTインターフェースを文書化する方法の良い例を誰かに公開してもらいたいです。非常に多くの悪い例があり、ユーザーに非常に貴重であることを示す有効な例があります。


2
ワオ。そのリソースモデルのページは私の目に涙をもたらしました。これがトレンドになることを期待しましょう。
ダレルミラー

これは基本的にWebでのそのようなAPIの唯一の例です。さらに悪いことに、(私が見つけた)原則に従うクライアントコードの良い例はまったくありません。
jkp 2009年

1
@DarrelMillerしかし、これらのメディアタイプは「特定」されすぎていませんか?彼らのAPIは本当に1つのMIMEのみを使用しているように思えますapplication/json。リソースモデルは真の関係です。RESTのこの側面を誤解していませんか?私もあなたのSOの回答の1つを読みました。 これは、これらの「1つの属性」の契約は避けられるべきだと指摘しているようです...
edsioufi

2
@RichApodacaあなたのリンクは赤痢で死にました。web.archive.org/web/20170409132237/https://kenai.com/projects/...
forresthopkinsa

5

私はHATEOASに従って書かれたAPIの良い例を探していて、それを見つけるのに問題がありました(SunCloud APIとAtomPubの両方を「通常の」APIの状況に適用するのは難しいと感じました)。そこで、適切なREST実装とはどういう意味かというRoy Fieldingsのアドバイスに従って、ブログで現実的な例を作ってみました。原則としてかなり単純であるにもかかわらず、この例を思い付くのは非常に難しいことがわかりました(WebページではなくAPIを操作する場合は混乱します)。Royが問題を抱えていたことに同意します。これは、APIを適切に実装するという考え方の転換に過ぎません。

見てみましょう:Restを使用したAPIの例


4

URIの作成方法を説明する1つの例外は、ハイパーテキスト応答でURIテンプレートを送信することが許可されていることです。フィールドは、ハイパーテキストの他のフィールドを使用して、クライアントによって自動的に置き換えられます。これは通常、帯域幅を大幅に節約することにはなりませんが、gzip圧縮はURIの繰り返される部分を十分に処理するため、これに悩まされることはありません。

RESTおよび関連するHATEOASに関するいくつかの良い議論:

RESTFul APIでHATEOASを使用する(また)の利点

一杯のコーヒーを手に入れる方法



4

ほとんどの人が誤解しているのは、RESTの世界では「Restインターフェース」を文書化しないことです(文書化するのはサーバーやサービスとは無関係にメディアタイプです)。


2

RESTが存在するようになって何年も経たないうちに、技術者たちはリソースの概念と、RESTfulとは実際に何がそうでないかを理解するようになったと思います。

Richardson Maturity Modelによれば、Roy Fieldingが意図したとおり、APIのRESTfulを定義する4つのレベル(0〜3)があり、3つは真にRESTfulなAPIを意味します。

レベル0は、SOAPのような1つのエントリポイントURIがある場合です。

レベル1は、APIが異なるリソースを区別でき、複数のエントリポイントがあることを意味します-それでもSOAPのにおいがします。

レベル2は、主にGET、POST、DELETEというHTTP動詞を使用する場合です。これは、RESTが実際に登場するレベルです。

レベル3では、ハイパーメディアコントロールを使用して、APIを真に RESTfulにします。

さらに読むための推奨リンク:


1

正解です。さらに、パターンがサーバーから受信したドキュメントからのものである限り(OpenSearchが適切な例です)、URIテンプレートはRESTfulアプリケーション内で完全に問題ありません。URIテンプレートの場合は、テンプレートが使用されている場所と、テンプレートで予期されるプレースホルダーが何であるかを文書化しますが、テンプレート自体は文書化しません。バーンフリーデンが言ったこととは少し反対ですが、これは例外ではありません。

たとえば、私の仕事では内部ドメイン管理システムがあり、サービスドキュメントは2つのURIテンプレートを指定します。1つはドメインリソースの最良推測URIを生成するためのもので、もう1つはドメインの可用性を照会するためのURIを構築するためのものです。ドメインコレクションをページングして、特定のドメインのURIが何であるかを把握することは引き続き可能ですが、管理するドメインの数が膨大であることを考えると、これはクライアントには実現できないため、クライアントに何を推測するかを与えることができます。ドメインリソースのURIは、クライアントから見た実装の容易さ、およびサーバーからの帯域幅の点で非常に有利です。

あなたの質問に:私たちの規範的なドキュメントは、公開されたリソース、それらのリソースに対するさまざまなメソッドの影響、使用される表現メディアタイプとそのスキーマ、およびそれらの表現のURIが指すリソースの種類です。

また、ドキュメントに記載されているURIを読みすぎないように免責事項を添付した非規範的(参考)文書も含まれています。これにより、典型的なクライアント/サーバー相互作用の例が示されます。これは、かなり抽象的な規範的な文書を具体的な言葉で表現しています。


1
APIの一部としてアウトオブバンドでURIテンプレートを提供しても問題ありません。これはRESTではないので、RESTと呼ばないでください。これは膨大な量の結合であり、RESTが回避するために作られたものです。しかし、あなたが言うように、RESTはすべてのアプリケーションに対応しているわけではありません。したがって、すべてのアプリケーションがRESTであるふりをしないでください。
aehlke

1
実際、私は同意します。それが私が言ったことだと思います。ただし、URIテンプレートをアウトオブバンドで提供する理由はまったくわかりません。
キースガガン、

0

GET /foos/createFormcreateに行くときに提供されなければならないフォームフィールド値を取得するために呼び出されたと仮定しましょうPOST /foos。さて、この特定のURL、つまりfooを作成するために使用される1はGET /foos/createForm、Fieldingの命題に従って、送信アクションリンクとして、応答内で言及されるべきですよね?
次に、アクションをよく知られているHttp動詞からアクションにマッピングすることの利点は何ですか。「コード/構成に関する規約」は無効になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.