最近、Hypermediaをアプリケーション状態のエンジン(HATEOAS)として読んでいます。これは、Web APIを「真にRESTful」にするために要求される制約です。つまり、基本的には、現在の状態から可能な遷移へのすべての応答へのリンクを含めることになります。
私の理解に基づいてHATEOASがどのようなものであるかを説明しましょう。何かを見逃した場合は、是正してください。
/
GET: {
"_links": {
"child": [
{ "href": "http://myapi.com/articles", "title": "articles" }
]
}
}
/articles?contains=HATEOAS
GET: {
"_items": [
{ "uri": "http://myapi.com/articles/0", "title": "Why Should I Care About HATEOAS?" },
{ "uri": "http://myapi.com/articles/1", "title": "HATEOAS: Problem or Solution?" }
],
"_links": {
"self": { "href": "http://myapi.com/articles", "title": "articles" },
"parent": { "href": "http://myapi.com/", "title": "home" }
}
}
POST: {
"title": "A New Article",
"body": "Article body",
"tags": [ "tag1", "tag2" ]
}
/articles/0
GET: {
"title": "Why Should I Care About HATEOAS?",
"body": "Blah blah blah"
"tags": [ "REST", "HATEOAS" ],
"_links": {
"self": { "href": "http://myapi.com/articles/0", "title": "article" },
"parent": { "href": "http://myapi.com/articles", "title": "articles" }
}
}
HATEOASは2つの主要な利点を提供すると主張されています:
ルートURIからサービス全体が検出可能になり、ドキュメントは不要になります。
クライアントはサーバーから切り離され、サーバーはURI構造を自由に変更できるようになります。これにより、APIバージョン管理の必要がなくなります。
しかし、私の見解では、サービスはURI構造以上のものです。それを効果的に使用するには、次のことも知っておく必要があります。
上記に基づいて、HATEOASは発見可能性と結合の問題のごく一部しか解決しません。上記の4つの側面を文書化する必要があります。これらの側面があるため、クライアントは引き続きサーバーに強く結合されます。クライアントの破壊を回避するために、APIをバージョン管理する必要があります。
それが提供する唯一の利点は、URL構造を多かれ少なかれ自由に変更できることです(ところで、原則 "クールなURIは変更されない" ?)。私の理解は正しいですか?
あなたの本能はほぼ正しいと思います。自明でないWebアプリケーションの場合、クライアントは構文だけでなく、実行していることのセマンティクスにも注意を払う必要があるため、これらの宣言された利点は実際にはそれほど優れていません。
しかし、それはあなたのアプリケーションがHATEOASの原則に従うべきではないという意味ではありません!
HATEOASreallyはどういう意味ですか?これは、アプリケーションを構築することを意味し、原則としてWebサイトのようになります、複雑なスキーマをダウンロードしなくても、実行する可能性のあるすべての操作を検出できます。 (洗練されたWSDLスキーマはすべてをカバーできますが、そうするまでに、実質的にすべてのプログラマーが理解する能力を超えて、書くことはできません!HATEOASは、そのような複雑さに対する反応として見ることができます。)
HATEOASは、豊富なリンクを意味するだけではありません。これは、HTTP標準のエラーメカニズムを使用して、何が問題かをより正確に示すことを意味します。 「waaah!いいえ」の代わりに、実際に何が間違っていたか、クライアントが何をしたかを説明するドキュメントを提供できます。また、サポートOPTIONSリクエスト (クライアントが使用できるHTTPメソッドを見つけることができるようにする標準的な方法) コンテンツタイプネゴシエーション。これにより、応答のフォーマットをクライアントが処理できるフォームに適合させることができます。これは、クライアントが重要なケースでシステムの使用方法を検索できるように、説明テキスト(または、おそらくそれへのリンク)を入力することを意味します彼らが知らない場合;説明文は人間が読めるものでも、機械で読めるものでもかまいません(必要に応じて複雑にすることもできます)。最後に、クライアントはリンクを合成しないことを意味します(クエリパラメータを除く)。クライアントは、リンクを伝えた場合にのみリンクを使用します。
リンクと百科事典的知識のための素晴らしいメモリを備えたユーザー(HTMLの代わりにJSONまたはXMLを読み取ることができるため、少し変な人)がサイトを閲覧することを考える必要がありますHTTP標準の、しかしそうでなければ何をすべきかについての知識はありません。
そしてもちろん、コンテンツタイプネゴシエーションを使用して、アプリケーションの使用を許可するHTML(5)/ JSクライアントを提供することもできます。結局のところ、RESTful APIが優れている場合、それを上に実装するのは簡単なはずです。
HATEOASには、RESTful APIとは何かを定義する2番目の柱、つまり標準化されたメディアタイプが付属している必要があります。 ロイフィールディング自身が言った
A REST APIは、リソースの表現に使用されるメディアタイプを定義するために、その記述的な努力のほとんどすべてを費やす必要があります。 ".
遷移を明示的に定義する標準化されたメディアタイプと、リソースを相互にポイントするハイパーテキストを使用すると、クライアントを壊すことなく任意の形式をとることができるリソースグラフを作成できます。 Web作業と同様に、実際には、ドキュメント間にリンクがあり、ドキュメントはHTMLで記述されており、それらのリンクをたどる方法を定義しています。 <a href>
はGET、<form>
はGETまたはPOST(およびGETの場合に使用するURLテンプレートを定義))、<link type="text/css">
is GET ... etc.これは、ブラウザが任意の構造化HTMLページとWebをナビゲートする方法です。
あなたがしたすべてのポイント
- 使用できるクエリパラメータとその可能な値
- jSON/XML/POST/PATCH/etcリクエストで送信する必要があるドキュメントの構造
- サーバーによって送信された応答の構造
- 発生する可能性のあるエラー
対処すべきポイントです標準化されたメディアタイプの定義による。もちろん、これはずっと難しく、「REST」APIを定義するときにほとんどの人が考えていることではありません。ビジネスエンティティを取得し、その属性をJSONドキュメントに変換してRESTful APIを作成することはできません。
もちろん、発生したことはRESTは、「複雑なSOAPyモノの代わりにHTTPを使用する」を意味するように何らかの形で希釈されました。HTTPとHyperTextを使用するだけではRESTfulになるには不十分で、これはほとんどの人が間違っていることです。
これは悪いことである必要はありません:REST長期的な保守性と発展性と引き換えにパフォーマンスと開発の容易さを犠牲にします。これは大きな起業家アプリケーションの統合のために作られました。ハードコードされたJSON構造が必要な場合があります。RESTと呼ばないでください。そのアドホックWeb APIだけです。それは、それが悪いことを意味するのではなく、単に、 RESTの制約。
参考文献
これが少し明確になることを願っています:)
送信する要求の種類に関する詳細情報を含む、より豊かな応答を提供するように努めるハイパーメディア形式がいくつかあり、さらに多くの情報で応答を充実させることを妨げるものは何もありません。
次に例を示します Siren ドキュメント:
{
"class": [ "order" ],
"properties": {
"orderNumber": 42,
"itemCount": 3,
"status": "pending"
},
"entities": [
{
"class": [ "info", "customer" ],
"rel": [ "http://x.io/rels/customer" ],
"properties": {
"customerId": "pj123",
"name": "Peter Joseph"
},
"links": [
{ "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
]
}
],
"actions": [
{
"name": "add-item",
"title": "Add Item",
"method": "POST",
"href": "http://api.x.io/orders/42/items",
"type": "application/x-www-form-urlencoded",
"fields": [
{ "name": "orderNumber", "type": "hidden", "value": "42" },
{ "name": "productCode", "type": "text" },
{ "name": "quantity", "type": "number" }
]
}
],
"links": [
{ "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
{ "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
{ "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
]
}
ご覧のように、関連するactions
の呼び出し方法に関する情報がメッセージで提供されており、この情報を解釈することで、クライアントは変更に対する抵抗力が高まります。
rel
sが固定語彙からではなく、検索可能なURIである場合、特に強力になります。
(HATEOAS)、Web APIを「真にRESTful」にするために主張されている制約
それを真のREST APIにする唯一のことは、1つの制約だけでなく、すべての制約を満たすことです。
しかし、私の見解では、サービスはURI構造以上のものです。それを効果的に使用するには、次のことも知っておく必要があります。..
そのため、他の制約、自己記述的なメッセージなどが必要です...
クライアントの破壊を回避するために、APIをバージョン管理する必要があります。
どのように試すにせよ、APIのバージョン管理を行う必要があります。 RESTクライアントでも、RDF語彙に基づいて、目的のページにアクセスする方法、フォローするリンク、および収集する必要のあるプロパティを知る必要があります。メッセージの説明。その語彙から何かを置換または削除する必要がある場合は、おそらくすべてのクライアントが機能しなくなるため、新しいバージョンが必要になります。したがって、RESTは、早期に公開する必要があるものではない(そしてAPIを常に変更しているときにモデルを理解する)必要はないと思います。それ以外の場合は、多くのバージョンがあります。最初に構築できる安定したドメインモデルが必要です...
HATEAOSサービスの「ドキュメントはもう必要ありません」とどこで読みましたか。あなたが言うように、あなたはまだリンクの意味論を文書化する必要があります。ただし、HATEOASを使用すると、ほとんどのURIの構造を文書化する必要がないため、永久に保持できます。
HATEOASを使用すると、サービスの実装者は、クライアントが依存するURIの小さなセットを変更することなく、実装を大幅かつ効率的に変更およびスケーリングできます。大きなセットよりも少数のエントリポイントを変更しない方が簡単です。したがって、サービスへのパブリックエントリポイントの数を減らし、サブリソース(HATEOAS)へのリンクを動的に提供すると、HATEOAS以外のサービスよりも「クールなURIは変更されません」を実際にサポートします。