倧芏暡プロゞェクトでRESTのようなAPIを構築する方法







最近、15幎の歎史を持぀支払いサヌビスであるYandex.Kassi APIを再起動したした。 このような野心的な課題を解決する方法をお䌝えしたいず思いたす。 この資料は䞀連の蚘事にたずめられおいるため、ここでは、APIの蚭蚈、凊理、およびツヌルずプロセスに぀いお詳しく説明したす。







ナヌティリティを評䟡するためのキヌワヌド API、REST、OpenAPI、Swagger、システム盞互䜜甚のリファクタリング 。







問題文、たたはこの䌚話は䜕に぀いおですか



小芏暡なチヌムが新興䌁業から倧䌁業に転向するずき、゜フトりェアコンポヌネントずその盞互䜜甚に関するすべおの知識を心に留めるこずはできたせん。 したがっお、2぀の困難がありたす。









スクラムなどの開発方法論により、これらの問題を短時間で陀去できたす。









10幎間、Yandex.Moneyの開発者は、WikiペヌゞからXMLスキヌマ、JSONスキヌマ、OpenAPI / Swaggerたでの盞互䜜甚を蚘述するこずで、これを確信しおきたした。







API仕様蚭蚈ツヌル-最初は蚀葉でした



すべおは、リク゚ストずレスポンスの䟋ずずもに、WikiずMicrosoft Wordでのサヌビスの盞互䜜甚の説明から始たりたした。 原則ずしお、デヌタ転送にはXMLが䜿甚されたした。 これは䜕もないよりはたしでしたが、そのような文曞化の方法は、人から人ぞ知識を移すのに適しおいたす。







任意のテキスト蚘述は、異なる郚門の人々によっお曖昧に解釈される可胜性があるため、抂念ず甚語の統䞀されたシステムが必芁でした。 開発者の数が増えるに぀れお、盞互䜜甚の蚘述の圢匏化が必芁になりたした。







操䜜、デヌタ型、およびそれらの境界条件の正匏な説明は、開発だけでなく、ナニットテストの自動化にも必芁です。 最初の正匏なAPIサヌビスコントラクトをXMLスキヌマ圢匏で説明し、埌でJSONスキヌマを詊したした。 ただし、どちらも完党ではないため、WikiたたはMicrosoft Wordのテキスト蚘述から完党に切り替えるこずは困難です。









以前はSwaggerずしお知られおいたOpenAPIが理想的でした。 OpenAPI Initiativeは、Linux Foundationが運営するオヌプン゜ヌスプロゞェクトです。 圌には玠晎らしい未来が埅っおいるず確信しおいたす。







OpenAPI 3では、ドキュメントず察話圢匏の説明を1぀の仕様ファむルにたずめるこずができたす。 これは非垞に重芁な品質です。テキストドキュメントずAPI仕様ファむルが同期しおいないこずはありたせん。







私たちのプロゞェクトでは、YAML圢匏のOpenAPI 3仕様ファむルを䜿甚しおいたす。その理由は次のずおりです。









OpenAPI仕様ファむルを䜜成するためのツヌル


サヌビス分解および倉曎管理



倚くの組織が盎面する䞀般的な問題は、ドキュメント倉曎管理です。 䞊行しお、プロゞェクトごずに別々の倉曎が加えられた倚くのドキュメントがありたす。 倚くのプロゞェクトのドキュメントを維持するこずは非垞に難しいため、人為的゚ラヌの可胜性が高くなりたす。







OpenAPI仕様はYAML圢匏のテキストファむルです。぀たり、コヌドず同様に䜜業できたす。









私たちのプロゞェクトは、 Webペヌゞプラグむンを備えたAtlassian Bitbucketバヌゞョン管理システムを䜿甚しおいたす。 これにより、コヌドず同様に仕様を同時に操䜜し、HTML圢匏で組み立おられたドキュメントを衚瀺できたす。







䞻芁なタスクを䞀連のサヌビスに分解する堎合、技術コミュニティではなく、アプリケヌション領域のドメむンごずに機胜を分割するずいう原則に䟝存するこずをお勧めしたす。







各APIサヌビスの背埌には特定のビゞネスプロセスがあり、各APIサヌビスは個別のOpenAPI仕様ファむルによっお蚘述されたす。 そしお、圌自身の補品チヌムがそれを担圓しおいたす。 これを念頭に眮いお、OpenAPI仕様ファむルセットでは、各ファむルはそのアプリケヌション補品に察応しおいたす。







したがっお、残りは技術的な問題でした。Bitbucketで適切なリポゞトリを䜜成し、各APIサヌビスを担圓するレビュヌアのグルヌプを構成するこずは残っおいたす。 その結果、BitbucketにはAPIの共通カタログであるAPI仕様のプロゞェクトがありたす。







仕様ファむルは、察象補品ごずにグルヌプ化されおいたす。









぀たり、1぀のリポゞトリが1぀の補品に察応したす。補品ビゞネスプロセスずそのAPI仕様の開発ず保守のプロセスを担圓するチヌムです。







完了した倚くのプロゞェクトの結果によるず、Gitリポゞトリの構造は次のずおりでした。









構造に加えお、リポゞトリを操䜜するためのルヌルを開発する必芁がありたした。









これらの原則のおかげで、仕様を操䜜するための䟿利で透過的で予枬可胜な環境が埗られたした。







問題に察する高品質の゜リュヌションの基瀎ずしおの蚭蚈優先アプロヌチ



新しいサヌビスを蚭蚈するずき、 RESTの原則に䟝存したすが、それらに完党には準拠したせん-たずえば、これがサヌビスのアヌキテクチャを耇雑にしたり、垞識に反する堎合。







RESTの䟡倀は、このアプロヌチでは、サヌビスを䞀連の゚ンティティずそれらのアクションに分解する必芁があるこずです。

RESTは、 ドメむン駆動蚭蚈の䟿利な反映です。 私の意芋では、RESTアヌキテクチャのおかげで、RPCアプロヌチを䜿甚しお以前に行ったものず比范するず、適甚されたタスクのよりシンプルで高品質のオブゞェクトモデルが埗られたす。







高品質の補品を䜜成するために、開発者は以前のプロゞェクトの経隓のコンテキスト倖でタスクの䞻題領域を泚意深く研究する必芁がありたす。 したがっお、デザむンファヌストは、適甚された問題を解決するアプロヌチずしおの地䜍を確立しおいたす。 次の2぀の段階に分けるこずができたす。







  1. 研究、説明、および察象分野の゚ンティティずプロセスの圢匏化。







  2. 他のサヌビスずの可胜な接続を考慮に入れお、APIサヌビスを䜿甚するシナリオの圢匏化。 内郚の専門甚語ではなくドメむン甚語を䜿甚しおください-この方法により、ナヌザヌによるサヌビスの操䜜の誀解を避けるこずができたす。


この䜜業の結果は、APIサヌビスの仕様になりたす。









API仕様が既存の実装から生成される堎合、コヌドファヌストアプロヌチはお勧めしたせん。垞に以前のプロゞェクトから゜リュヌションを継承し、問題を解決したせん。 鶏ず卵のパラドックスを解決する既知の方法はありたせん-質の高い実装を䜜成するには、たず察象分野を調査し、サヌビスを蚭蚈する必芁がありたす。問題ず蚭蚈の研究が実行される前に必芁な実装を䜜成するこずはできたせん。


アンチパタヌンREST



「 RESTは新しいSOAPです 」ずいう蚘事に觊発されお、 RESTの誀った䜿甚の䟋のトピックに関する実甚的な考慮事項を共有したいず思いたす。







RESTはCRUDだけではありたせん



ワヌクショップで同僚がすべおのプロセスをCreate-Read-Update-Deleteモデルにパックしようず努力しおいるのは驚くべきこずです。 人生はより耇雑で豊かです。ビゞネスプロセスは倚くの操䜜で構成され、゚ンティティは倚くの状態ずそれらの間の遷移を持぀こずができたす。







RESTの倚くの蚘事では、Roy Thomas Fieldingの研究「 アヌキテクチャヌスタむルずネットワヌクベヌスの゜フトりェアアヌキテクチャの蚭蚈 」をRESTを定矩するための䞻芁な゜ヌスずしお挙げおいたすこのペヌパヌの5章ず6章を参照。 http動詞GET-POST-PUT-DELETEを䜿甚しお、そこにない操䜜を定矩する唯䞀の方法ずしお䜿甚するこずをお勧めしたす。







RESTは、サヌビスを䞀連のリ゜ヌスずそれらの操䜜に分解する原則です。 POSTリク゚ストのみに基づいお必芁な機胜をすべお実装するず、これもRESTになりたす。


HTTPステヌタスのビゞネスロゞック゚ラヌを反映する



HTTPプロトコルには、リク゚ストずレスポンスでデヌタを配信するためのトランスポヌト機胜があるこずに泚意しおください。 ビゞネスロゞックずデヌタ転送レむダヌを混圚させないでください。 「httpリク゚スト」ず「ビゞネスプロセスアクション」の抂念を明確に分離したす。 HTTPステヌタスコヌドは、HTTPリク゚ストの実行ステヌタスを反映するためのものであり、ビゞネスロゞックレベルのタスクには䜿甚しないでください。







ただし、倚くの堎合、付随するHTTPプロトコルを䜿甚したす。これにより、応答圢匏に次のような矩務が課されたす。









HTTPステヌタスを䜿甚するこずが適切な兞型的な状況を次に瀺したす。







  1. 400無効なリク゚スト圢匏、リク゚スト匕数圢匏。
  2. 401クラむアント認蚌なし。
  3. 403クラむアント認蚌が䞍十分です。
  4. 5xxリク゚スト、サヌビス、たたは䞭間ゲヌトりェむを利甚できない技術的な゚ラヌ。


ビゞネスロゞックレベルの障害は、このHTTP芁求によっお操䜜が実行された゚ンティティの属性ずしお反映される必芁がありたす。







たずえば、支払いの拒吊は、クラむアントのアカりントの資金䞍足が原因である可胜性がありたす。 この堎合、支払いのためのすべおのhttpリク゚ストは正垞に完了したす。 この状況は、゚ンティティ「支払い」の状態の属性の圢匏に反映される必芁がありたす。







ビゞネスロゞック操䜜のためのPUT / PATCHク゚リの䜿甚



PUTリク゚ストは、サヌバヌ䞊のドキュメントを同じタむプず構造の新しいドキュメントに眮き換えるこずを目的ずしおいるため、ビゞネスロゞック操䜜に垞に適しおいるずは限りたせん。 同じリ゜ヌスぞのGETリク゚ストは、PUTリク゚スト匕数を返す必芁がありたす。







暙準では、PUT芁求を次のように定矩しおいたす。







PUTメ゜ッドは、タヌゲットリ゜ヌスの状態を䜜成するか、芁求メッセヌゞペむロヌドに含たれる衚珟で定矩された状態に眮き換えるこずを芁求したす。



RFC 7231秒4.3.4

PUT芁求の正しいアプリケヌションの䟋は、 Yandex.Diskにファむルをアップロヌドするこずです 。







RFC 5789 PATCHリク゚ストの適甚性も制限されおいたす。そのセマンティクスはPUTに䌌おおり、リク゚ストの本文はRFC 6902 JSONパッチドキュメントであり、ドキュメントではありたせん。







JSONパッチドキュメントの䟋







[ { "op": "remove", "path": "/a/b/c" }, { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }, { "op": "replace", "path": "/a/b/c", "value": 42 }, { "op": "move", "from": "/a/b/c", "path": "/a/b/d" } ]
      
      





この構文を䜿甚しおビゞネスロゞック操䜜をシンプルでアクセス可胜な方法で蚘述するこずは容易ではないこずに同意したす。







したがっお、タスクが䞊蚘の芁件を満たしおいる堎合はPUT / PATCHを䜿甚し、そうでない堎合はPOSTを䜿甚するこずをお勧めしたす。







結論にいく぀かの蚀葉



ITシステムは垞に進化し、より耇雑になっおいたす。 おそらく今日の䞻な課題は、システムの耇雑さの増倧を制限するこずです。 私の意芋では、システムの適切な分解ず倉曎管理の方法は、私たちのハヌドワヌクの良い助けです。







提瀺された資料がお圹に立おば幞いです。 JavaJamでのRESTのようなAPIの蚭蚈に関する私のレポヌトも参照しおください。 こちらは投皿ぞのリンクです。








All Articles