ハむパヌメディア-APIがなければRESTにはなりたせん

みなさんこんにちは 私の同僚であるAlign TechnologyのDmitry Pavlovず申したす。瀟内システムの盞互䜜甚ずサヌドパヌティベンダヌずの統合のためのWeb APIを開発しおいたす。 この蚘事では、Web甚のAPI、たたはRESTful APIを䜜成するためのアむデアに぀いおお話したす。







近幎、Web APIトピックは非垞に人気が出おきおおり、倚くの䌁業が、オヌプンで内郚䜿甚の䞡方のようなむンタヌフェヌスを䜜成しおいたす。 Web APIの説明では、ほずんどの堎合、頭字語RESTを芋぀けるこずができたすが、この甚語は䜕を意味し、正しく䜿甚されおいたすか







RESTたたはRESTではない



ほずんどの開発者、特にロシアでは、RESTがHTTP [S]プロトコルを䜿甚しお動䜜する゜フトりェアむンタヌフェヌスずしお理解されおおり、次の特性がありたす。









通垞、このようなAPIが䜿甚されるアルゎリズムは暙準です。 たず、ドキュメントを䜿甚しおWebサむトにアクセスし、リ゜ヌスにアクセスするためのURLパタヌンのリストを含むペヌゞを芋぀ける必芁がありたす。 通垞、次のようになりたす。







    API " " --- /recipes/cookies -   , GET   URL     [ { "name" : "   ", "rating" : 5, "shortDescription" : "...." } ] POST   URL     .      json   { "name" : " ", "shortDescription" : "...." ...... } --- /recipes/cookies/:name -     ${name} { "name" : "   ", "rating" : 5, "shortDescription" : "....", "description" : "...." "ingredients" : [ { "name" : "", ..... }, { "name" : "", ..... }, { "name" : "", ..... } ], "cookingSteps" : [ .... ] } //    API   HTTP   URL 
      
      





そしお、それを調べお、リ゜ヌスにリク゚ストを行いたす通垞、これは、指定されたURL圢匏のパラメヌタヌを眮換し、応答を凊理するクラむアントを䜜成するこずで衚されたす。







ネットワヌクのオヌプンスペヌスには、このようなAPIの䟋がたくさんありたす。最近たで、Yandexには、このスキヌムに埓っお機胜するRESTずしお宣蚀された倚くのAPI 1、2 がありたした。







䞻な情報源、぀たり ロむ・フィヌルディングの論文しばしば参照されたすが、あたり読たれたせんに぀いおは、この方法で䜜成されたAPIは、論文で説明されおいる原則のいく぀かに違反するため、RESTず呌ぶこずはできたせん。最も重芁なのはハむパヌメディアの䜿甚です状態管理ツヌルHypermedia As The Engine Of Application State、HATEOASずしお、間接的に自己蚘述メッセヌゞに察凊したす。







メッセヌゞ内のハむパヌメディア



HATEOASの本質は、APIのリ゜ヌスを蚘述するためのアプロヌチです。 クラむアントが呌び出すこずができるすべおの可胜な操䜜のリストを䜿甚しお、リ゜ヌスのセットを単玔にリストする代わりに、いく぀かの内郚ロゞックに基づいお、制埡の反転を実行したす-サヌバヌはリ゜ヌスの状態を担圓し、リ゜ヌスに察しお珟圚実行できる操䜜をクラむアントに指瀺したす。 この情報は、クラむアントが受信するリ゜ヌスのたさに衚珟に存圚する必芁がありたす。 したがっお、リ゜ヌスのプレれンテヌション自䜓は、クラむアントがそれで䜕ができるかを理解するのに十分なほど説明しおいたす。







通垞、このアプロヌチの適甚は、クラむアントが「゚ントリポむント」の有限セットを知っおいるこずを意味したすサむトの開始ペヌゞに類䌌しおいるずみなすこずができたす。 。







この目暙を達成するために、ハむパヌリンクが䜿甚されたす。









関連するリ゜ヌスず利甚可胜なアクションの䞡方ぞのリンクがないため、この操䜜はリ゜ヌスの珟圚の状態では利甚できたせん。







ハむパヌメディアビュヌでのCookies Recipes API凊理の䟋



Cookieレシピのディレクトリに関するAPIを䜿甚した䟋に戻り、それをハむパヌメディアビュヌに倉換したす。







ご存知のように、レシピのリストず、材料ず調理手順をリストした特定のレシピを詳述したリ゜ヌスがありたした。 ハむパヌメディアアプロヌチを䜿甚するず、次のようになりたす。







 //  { "links": { "self" "/recipes/cookies" } "items": [ { "name": "   ", "rating": 5, "shortDescription": "...." "links": { "self": "/recipes/cookies/   " } } ] } //  { "links": { "self": "/recipes/cookies/   " } "name": "   ", "rating": 5, "shortDescription": "....", "description": "...." "ingredients": [ { "name": "", ..... }, { "name": "", ..... }, { "name": "", ..... } ], "cookingSteps": [ .... ] }
      
      





元のバヌゞョンずの倧きな違いは、各リ゜ヌス内のlinks



オブゞェクトの倖芳です。 このオブゞェクトのキヌは関係同じ識別子であり、倀はリンクです。 その結果、レシピカタログから詳现な説明に進む方法に関する远加情報リ゜ヌス自䜓の倖郚はリ゜ヌスに必芁ありたせん。リンクはリ゜ヌスのプレれンテヌションに組み蟌たれたす。







このアプロヌチにより、APIの機胜を簡単に拡匵できたす。 各レシピに぀いお、レシピのリストの圢匏で提瀺される䞀連の掚奚事項をクラむアントに提䟛するずしたす。 これは非垞に簡単です。リンクオブゞェクトに新しいキヌを远加するだけです。







 "links" : { "self" : "/recipes/cookies/   ", "http://acme.com/recipes/rels/you-can-also-like" : "/recipes/cookies?related_to=+++" }
      
      





同様に、必芁に応じお、成分の識別情報を個別のリ゜ヌスずしお远加するこずはたったく難しくありたせん。







API芁玠はリレヌションであるため、URIのコンテンツは䜕の圹割も果たさず、クラむアントでの倉曎なしに、 /recipes/related-to/



たたは/recipes/234892skfj45sdlkfjdsa12



ぞのリンクを倉曎できたす







倉曎サヌビスのハむパヌメディア



ハむパヌメディアは、ナビゲヌションだけでなくアクションの実行にも䜿甚されたすが、リ゜ヌスに察する特定の操䜜を実行する責任がある関係を特定し、これらの操䜜のセマンティクスず詳现を瀺すだけで十分です。







わかりやすくするために、ハむパヌレシピを远加しお新しいレシピを䜜成するAPIの䟋を怜蚎しおください。







 //  { "links" : { "self" : "/recipes/cookies", "http://acme.com/recipes/rels/add-recipe" : "/recipes/cookies" } "items" : [ ..... ] }
      
      





特別な関係を持぀リンクを远加したした。 基本的なルヌルは、クラむアントが知らない関係を無芖するこずです。新しいレシピを远加する方法を知らない「叀い」顧客は以前ず同じように動䜜したすが、䜜成をサポヌトする堎合、これはリク゚ストを送信するこずで新しいレシピを远加できるずいうシグナルになりたすhttp://acme.com/recipes/rels/add-recipe



に関連しお参照されるURI







このアプロヌチにより、静的な䞀連の操䜜ずその実装の条件をドキュメントに蚘述するのではなく、サヌバヌに盎接蚘述しお、クラむアントが特定の時間にリ゜ヌスで実行できる操䜜ずできない操䜜を制埡できたす。 新しいアクションを远加するこずも難しくありたせん。新しいリレヌションを宣蚀し、サヌバヌが圢成するリ゜ヌス衚珟にそれを含め始めるだけです。







もちろん、リンクを提䟛しおも、サヌバヌがHTTPメ゜ッドを正しく凊理し、セマンティクスを監芖する責任を免れるこずはありたせん:)。







しかし、関係はどうですか



珟時点では、おそらく疑問がありたす効果的な仕事のためにクラむアントが関係の意味をただ理解する必芁がある堎合、これをすべお開始するポむントは䜕ですか それらのドキュメントが必芁です。







実際、効果的な仕事のために、クラむアントは各関係が䜕を意味するのかを本圓に理解する必芁がありたす。 URIの解釈をリレヌションに眮き換える背埌にある䞻なアむデアは、リレヌションをより氞続的にするこずです。 URIは実装の詳现であり、時間の経過やサヌバヌごずに倉化する可胜性がありたす。 関係は通信のセマンティックな蚘述であり、ストレヌゞの詳现ずは関係ありたせん。







レシピを保存するための互換性のあるAPIを䜜成したいずしたすが、ストレヌゞの性質䞊、各レシピを名前ではなくUUIDで識別したいずしたす。 元のAPIの堎合、これは䞍可胜ですが、ハむパヌメディアAPIの堎合、クラむアントにはたったく芋えたせん。







その結果、サヌバヌ䞊で倉曎が行われた堎合に倉曎の圱響を受けにくい、より汎甚的なクラむアントを䜜成するこずが可胜になりたす。







ハむパヌメディアの皮類たたはアプリケヌション/ jsonが私たちに合わない理由



Hypermediaのアプロヌチを掻甚するこずにしたので、䞊蚘の方法でAPIを倉曎したした。そしお、参照によっお互いにリンクされたリ゜ヌスができたした。 䞀芋、すべおがAPIの順序どおりになっおいるように芋えるかもしれたせんが、Hypermedia APIがあるこずを宣蚀する前に、応答で返されるContent-Typeヘッダヌを芋おみたしょう。 そこにapplication/json



たたはtext/plain



堎合でも、匕き続き䞀生懞呜働く必芁がありたす。







機械の目から芋たリ゜ヌス



私たちが持っおいるリ゜ヌスを芋るず、人々はすぐにリンクを遞択し、メッセヌゞの正しい圢匏の印象を䞎えたす。 メッセヌゞの内容を分析するこずでこれを終わらせ、これが暙準がContent-Type応答ヘッダヌを調べるこずを芏定する方法です。







次のサヌバヌ応答を考慮しおください。







 200 OK Content-Type: text/plain <?xml version="1.0"?> <hello>world</hello>
      
      





答えにはxml-documentが含たれおいるこずは明らかですが、Content-Typeはコンテンツをプレヌンテキストずしお認識するように指瀺しおいるため、xml-documentは単なる偶然たたは特殊なケヌスになりたす。 そのため、真のContent-Typeが非垞に重芁です。







どのapplication/json



タスクに適しおいないのかを理解したしょうか 実際、この型を蚘述する暙準は、その型の参照を定矩するための堎所やメカニズムを提䟛しおいたせん。 たた、生成したメッセヌゞにリンクが含たれおいる堎合でも、マシンはそれらをリンクに䌌た圢匏のテキストを含む行ず区別できたせん。 ただし、リンクがメッセヌゞのどこにあるか、どこにないかを明確に刀断する必芁があるため、別のタむプが必芁です。







ベンダヌ固有のタむプ



Content-Typeの正確性の問題を解決する1぀の方法は、独自のものを䜿甚するこずです。 ドキュメントでは、メッセヌゞ内のリンクの堎所を明確に瀺したす。 クラむアントが私たちの個人的なContent-Typeを䜿甚しおサヌバヌから応答を受け取った堎合、もちろん、圌がContent-Typeを理解しおいない限り、リンクが䜕であるかを動的に掚枬する必芁はありたせん。 倚くの堎合、タむプを説明するドキュメントには、フォヌマット自䜓の詳现リンクの堎所、プロパティの堎所だけでなく、その他の情報も含たれおいるこずに泚意しおください。









このようなタむプは、特定のタスクおよび特定の組織甚に䜜成されるこずが倚いため、ベンダヌ固有ず呌ばれたす。 IANAに登録する必芁はありたせん。 フォヌムapplication/vnd.${vendor}+${base_format}



名前を付けるこずをお勧めしたすapplication/vnd.${vendor}+${base_format}



ここで、 ${vendor}



は䌚瀟の逆ドメむン、 ${base_format}



はベヌスずしお䜿甚したタむプです。 䌚瀟にacme.comドメむンがあり、jsonを䜿甚しおリ゜ヌスを衚す堎合、レシピAPIのタむプ名はapplication/vnd.com.acme.recipes+json



ようになりapplication/vnd.com.acme.recipes+json



。







ハむパヌメディアの䞀般的なタむプ



䞀芋、ベンダヌ固有のタむプはリンクの問題を解決したすが、独自の問題もありたす。









別の方法ずしお、汎甚タむプがもたらした新しいアプロヌチは間もなく登堎したす。 考えおみるず、メッセヌゞ圢匏に必芁なのは、質問に答える仕様だけです。









解決されおいるのはこの問題です。汎甚タむプは特定のドメむンドメむンに適応しようずせず、凊理するリ゜ヌスのほずんどを蚘述するこずができたす。







すべおのタむプの汎甚の重芁な機胜は、ドキュメントのセマンティック蚘述のタスクを匕き起こさないこずです。 レシピの説明やブログぞのコメントなど、それがどのようなリ゜ヌスであるかを䌝えたせん。これは圌らの仕事ではありたせん。 圢匏の詳现を担圓し、セマンティック仕様をそのたた䜿甚できたす。 セマンティクスは、いわゆるプロファむルプロパティず関係リレヌションのセマンティクスを説明する別個の文曞で囲たれるこずが想定されおいたす。







珟時点では、そのようなフォヌマットはすでにかなり倚数あるため、そのうちのいく぀かをリストしたす。









このようなすべおの圢匏の説明には、リ゜ヌスのプロパティを配眮する方法ず堎所、他のリ゜ヌスぞのリンクを䜜成する圢匏が蚘茉されおいたす。







タむプ自䜓に含たれる圢匏ず機胜が異なりたす。







クリ゚むタヌの圢匏や原則の違い



ほずんどの汎甚タむプには、リンクのフォヌマット方法など、现かい郚分がありたす。 そのため、HALでは、リンクは次のようになりたす。







 "_links" : { "self" : .... "relToResource": ..... }
      
      





䞀方、Sirenは次のように衚瀺したす。







 "links" : [ {"rel" : ["self"], "href" : "...."}, {"rel" : ["relToResource"], "href" : "...."} ]
      
      





ここでの䞻な違いは、関係倀の衚珟です。 HALの䜜成者はフォヌマットをより簡朔にしたかったのに察し、Sirenの䜜成者はそれをより完党なものにしたかったのです。リンクではリレヌションが本圓に耇雑になる可胜性がありたすこれがSirenの倀の配列である理由ですが、これは垞に䜿甚されるわけではありたせんオブゞェクト内。







このようなさたざたなビュヌにより、さたざたな圢匏が䜜成され、単䞀の圢匏に同意するこずはできたせんでした。







機䌚の違い



ここでは、フォヌマットのすべおの違いをリストするのではなく、すでに述べたタむプを䟋ずしお䜿甚しお、䞻なもののみを抂説したす。









汎甚ずベンダヌ固有



どちらのオプションが望たしいか特別に䜜成されたタむプか、既存のオプションの1぀ですか 通垞、同様の質問の堎合ず同様に、それに察する明確な答えはありたせん。すべおは䜿甚状況に䟝存するため、それぞれの利点ず欠点を匷調しおみたしょう。







汎甚ハむパヌメディアタむプの䞻な利点の1぀は、ナヌザヌずAPIクラむアントの時間を節玄できるこずです。 それはそれを通しお達成されるものです









同時に、このアプロヌチの利点のいく぀かは欠点のように芋えるかもしれたせん。 この型はどのドメむン領域やタスクにも結び付けられおいないため、䜜成できる特殊な型ず比范しお、リ゜ヌスの衚珟はより「肥倧化」しおいたす。







その結果、ほずんどのタスクで、デフォルトの汎甚ハむパヌメディア圢匏のいずれかを䜿甚するこずをお勧めし、耇雑たたは特定のケヌスでベンダヌ圢匏を遞択できたすもちろん、ベンダヌロックむンの目暙を蚭定しない限り。







これはどれくらい必芁ですか



説明したアプロヌチは、APIの開発におけるすべおの問題を解決するために蚭蚈された別の特効薬ではありたせん。







゚ントリポむントの抂念は、目的のリ゜ヌスに「到達」するためのリク゚スト数の増加に぀ながる可胜性があり、リンクを含めお、ベアデヌタず比范しおメッセヌゞをより倚くするこずに泚意できたす。







これらの問題は、よく考え抜かれたリ゜ヌス構造クむックナビゲヌションの゚ントリポむントでリ゜ヌス怜玢操䜜を実行できないのは誰ですか、キャッシングこのアヌキテクチャアプロヌチの重芁なコンポヌネントずしおフィヌルディングでも指摘されおいる、およびWebサヌバヌでの圧瞮の通垞の包含によっお解決されるずいうこれらの欠点に反察するこずができたす。







RESTが提䟛する柔軟性ず拡匵性におけるRESTアプロヌチここでは完党なRESTの䞻な利点は、既存のクラむアントの䜜業を䞭断するこずなく、サヌバヌ䞊のリ゜ヌスの構成を倉曎したり、新しい機胜を远加したりできるこずです。







APIでハむパヌメディアを䜿甚しないこずにした堎合でも、それなしではRESTはRESTではなく、単なるWeb APIであるこずがわかりたす。 これはAPIを良いものにも悪いものにもせず、事実を述べおいるだけです。 , API API, , :).












All Articles