web-dev-qa-db-ja.com

RESTful APIランタイムの発見可能性/ HATEOASクライアントの設計

私が関与しているSaaSスタートアップでは、RESTful Web APIと、それを使用するさまざまなプラットフォームでのクライアントアプリの両方を構築しています。私はAPIを理解したと思いますが、今はクライアントに目を向けています。 RESTについて読んでいると、RESTの重要な部分はdiscoveryであることがわかりますが、発見が実際に意味するものの2つの異なる解釈の間の多くの議論:

  1. 開発者の発見:開発者は、リソースURI、クエリパラメータ、サポートされているHTTPメソッド、ドキュメントの閲覧や実験を通じて発見したその他の詳細など、APIの詳細の多くをクライアントにハードコードしますAPIの応答を使用します。私見のこのタイプの発見は、クールなリンケージとAPIバージョン管理の質問を必要とし、クライアントコードのAPIへのハードカップリングにつながります。十分に文書化されたRPCのコレクションを使用する場合よりもはるかに良くないようです。

  2. 実行時検出-クライアントアプリ自体は、帯域外情報をほとんどまたはまったく必要とせずに、必要なすべてを把握できます(おそらく、APIが扱うメディアタイプの知識のみ)。暑い。しかし、APIを非常に効率的にするには、クエリパラメータのリンクテンプレートを大量に作成する必要があるようです。これにより、帯域外情報が戻ってきます。まだ考えていない他の困難があるかもしれません。開発のその時点に到達しました。しかし、私は疎結合のアイデアが好きです。

ランタイムディスカバリーはRESTの聖杯のようですが、そのようなクライアントを実装する方法については貴重な議論がほとんど見られません。私が見つけたほとんどすべてのRESTソースは、開発者による発見を想定しているようです。ランタイムディスカバリリソースを知っている人はいますか?ベストプラクティス?実際のコードを含む例またはライブラリ?私は1つのクライアントに対してPHP(Zend Framework)で作業しています。もう一方はObjective-C(iOS)。

開発者コミュニティのツールと知識の現在のセットを考えると、ランタイムの発見は現実的な目標ですか?クライアントを記述して、すべてのURIを不透明な方法で処理できますが、これを最も効率的に行う方法は、特に低帯域幅の接続で問題になります。とにかく、URIは方程式の一部にすぎません。ランタイムコンテキストでのリンクテンプレートはどうですか?多くのOPTIONSリクエストを作成する以外に、どのメソッドがサポートされているかを伝えるのはどうですか?

77
curtisdf

このビデオでは、Jon MooreがランタイムHATEOAS自動検出を使用して汎用クライアントを構築します。それはかなり印象的で、見る価値があります:

http://oredev.org/oredev2010/2010/sessions/hypermedia-apis.html

33
Ferenc Mihaly

これは間違いなくクラックするのが難しいナットです。 Googleでは、すべての新しいAPIが構築されるディスカバリサービスを実装しました。 TL; DRバージョンは、クライアントが解析できるJSONスキーマのような仕様を生成します-それらの多くは動的に。

その結果、開発者にとってのSDKのアップグレードが容易になり、メンテナンスが容易/改善されました。

決して完璧な解決策ではありませんが、私たちの開発者の多くは気に入っているようです。

詳細については、 link を参照してください(およびビデオを必ず確認してください)。

19
jonathanberi

魅力的です。あなたが説明しているのは、基本的にはHATEOASの原則です。 HATEOASとは何ですか?これをお読みください: http://en.wikipedia.org/wiki/HATEOAS

素人の用語では、HATEOASはリンクをフォローすることを意味します。このアプローチにより、クライアントが特定のURLから切り離され、APIを変更する柔軟性が提供されます。

11
Sam

あなたはあなたの家の仕事をし、その核心に到達しました:ランタイム発見は聖杯です。追いかけてはいけません。

UDDIは、ランタイムディスカバリーの感動的なストーリーを伝えます。 http://en.wikipedia.org/wiki/Universal_Description_Discovery_and_Integration

6
Yuriy Zubarev

APIを「RESTful」と呼ぶ前に満たすべき要件の1つは、そのAPIの上に汎用クライアントアプリケーションを記述できることです。汎用クライアントでは、ユーザーはすべてのAPIの機能にアクセスできる必要があります。汎用クライアントとは、メディアタイプによって定義された構造を超える特定の構造をリソースが持っていることを前提としないクライアントアプリケーションです。たとえば、Webブラウザは、HTMLフォームなどを含むHTMLの解釈方法を知っている汎用クライアントです。

次に、Webショップ用のHTTP/JSON APIがあり、顧客に優れたユーザーエクスペリエンスを提供するHTML/CSS/JavaScriptクライアントを構築するとします。そのクライアントをgenericクライアントアプリケーションにするのは現実的なオプションでしょうか?いいえ。特定のデータ要素および特定のアプリケーションの状態ごとに特定のルックアンドフィールを提供する必要があります。これらのプレゼンテーション固有のすべての知識をAPIに含める必要はありません。反対に、クライアントはルックアンドフィールを定義し、APIはデータのみを保持する必要があります。これは、クライアントが特定のリソース要素と特定のレイアウトおよびユーザーインタラクションをハードコーディングしたカップリングを持っていることを意味します。

これはHATEOASの終わりであり、したがってRESTの終わりですか? はい、いいえ

はい、APIに関する知識をクライアントにハードコーディングすると、HATEOASの利点が失われるため、サーバー側の変更によりクライアントが破損する可能性があるためです。

いいえ、2つの理由:

  1. 「RESTful」であることは、クライアントではなくAPIのプロパティです。 理論上が可能な限り、APIのすべての機能を提供する汎用クライアントを構築するために、APIはRESTfulと呼ばれます。クライアントがルールに従わないという事実は、APIのせいではありません。汎用クライアントのユーザーエクスペリエンスが粗末であるという事実は問題ではありません。 実際に持っていないそのジェネリッククライアントがある場合、possibleであることを知ることが重要なのはなぜですか?これにより、2番目の理由がわかります。
  2. RESTful APIは、クライアントがどの程度汎用的になりたいか、つまり、サーバー側の変更に対してどの程度回復力があるかを選択するオプションを提供します。優れたユーザーエクスペリエンスを提供する必要のあるクライアントは、URIの変更やデフォルト値の変更などに対しても回復力がある場合があります。ユーザーの操作なしでバッチジョブを実行するクライアントは、他の種類の変更に対して回復力がある場合があります。

実際の例に興味があるなら、私の JAREST論文 をチェックしてください。最後のセクションはHATEOASについてです。 JARESTを使用すると、非常にインタラクティブで視覚的に魅力的なクライアントでさえ、サーバー側の変更に対して100%ではなく、非常に回復力があることがわかります。

4

基本的なランタイムディスカバリクライアントの別の例については、HAL Talk Hypermedia APIクライアントデモをご覧ください。

ハイパーテキストアプリケーション言語(リンク用のXML + JSONスキーマ)に基づく: http://stateless.co/hal_specification.html

2
papercowboy

HATEOASの重要な点は、それがクライアントサイドの聖杯であるということではなく、クライアントをURIの変更から隔離することではないと思います-システムがオブジェクトのどのリンクが編集可能なフォームであるかを知る。重要なポイントは、ハイパーメディア対応のemdiaタイプ(HTML、XHTMLなど)を使用することです。

1
Falkayn

あなたが書く:

APIを非常に効率的にするには、クエリパラメータのリンクテンプレートを大量に作成する必要があるようです。これにより、帯域外の情報が戻ってきます。

そのリンクテンプレートが前のリクエストで提供されている場合、帯域外情報はありません。たとえば、HTML検索フォームではリンクテンプレート(/search?q=%@)URLを生成する(/search?q=hateoas)。ただし、HTMLフォームとGETの使用方法以外は、クライアント(Webブラウザー)には何も認識されていません。

0
Nicholas Shanks