
2025.02.18
「売上をスケールする」AIの使い道とは アルペンが挑む、kintone×生成AIの接客データ活用法
openapi と swagger TS codegen(全1記事)
リンクをコピー
記事をブックマーク
菅原弘太郎氏(以下、菅原):それでは「OpenAPI GeneratorとTypeScriptによる型安全なスキーマ駆動開発」と題して、発表します。自己紹介します。2020年11月に、フロントエンドエンジニアとしてREADYFORに入社しました。岩手県在住で、フルリモートで勤務しています。ReactとTypeScriptが好きで、React Hook Formのメンバーなので、もしフォローしてくれる方がいれば、フォローしてください。
まずはフロントエンドとバックエンドの分離について話します。READYFORのサービスは、さまざまドメインが入り組んだ、1つのモノリスなサービスです。これがドメインごとに分離されたサービスを目指しています。
現状、フロントエンドとバックエンドの分離フェーズで、フロントエンドはTypeScriptとNext.jsを用いたSPA、バックエンドはREST APIという構成になっています。
私はちょうどフロントエンドとバックエンドの分離フェーズ中に入社しました。スキーマ駆動開発を実施している話は聞いていましたが、「はたして何だろう」という状態でした。
自分の3ヶ月前と同じような方がいるかもしれないので、今日は、スキーマ駆動開発とは何か、どんなメリットがあるのか、スキーマ駆動開発を実践する上でどんなツールを活用しているのか。3ヶ月、スキーマ駆動開発を実践してみた所感などを話せればと思います。これからスキーマ駆動開発を実践したい方の参考になれば幸いです。
まずはスキーマ駆動開発ついて説明します。SPAとAPI開発において、さまざまな悩みごとがあると思います。例えば、API仕様書のフォーマットが人によってバラバラだったり、仕様書と実装の乖離が発生したり。APIの実装を待たないとフロントの開発に着手できなかったり、あとはフロント側で想定していたリクエストやレスポンスが返ってこなかったりということがあるかと思います。
ここで、スキーマ駆動開発の出番です。まずスキーマ駆動開発のスキーマについて説明します。スキーマとは、ある定められた形式で記述したものです。Web APIの仕様定義と思ってもらって問題ありません。エンドポイントや、リクエストやレスポンスのデータ構造、値の型やフォーマットなどを定義したものを指します。
では、スキーマ駆動開発がどんなものかというと、Web APIの開発者と利用者、いわゆるバックエンドエンジニアとフロントエンドエンジニアでスキーマ設計を行い、スキーマを中心としたスキーマファーストな開発を行うことです。
これを実現するためには、さまざまなツールを活用する必要がありますが、スキーマが中心になって、ドキュメントの生成やコードの生成、モックサーバーの起動ができるようになります。
続いて、開発フローの違いについてです。スキーマ駆動開発以前では、APIが実装されてからフロントの実装に入るパターンがほとんどかと思います。これはフロント側でモックデータなどを用意すれば一応解決はできますがそもそも用意するのが面倒だったり手間がかかったりします。
これがスキーマ駆動開発を実践することでどうなるかというと、フロントとバックエンドでスキーマの設計を行って、コード生成ツールやモックサーバーを活用することで、APIの実装を待たずにフロント側で実装に入れます。
それでは、READYFORで活用しているツールの紹介です。まずはスキーマ定義から見ていきます。
知っている方も多いとは思いますが、READYFORではOpenAPIでスキーマを定義しています。Swaggerと聞けば知っている方がほとんどだと思うのですが、これはWeb APIを記述するためのフォーマットで、JSONやYAML形式での記述が可能です。READYFORではOpenAPI 3.0を使用しています。
イメージ的にはこのような感じになっています。左側がOpenAPIで定義したスキーマですが、「string型のpetIdのパラメータを、petsエンドポイントに対してGETリクエストすることによって、id・name・tagを含んだJSON形式で200レスポンスするよ」という意味合いになります。
続いてスキーマ定義の仕方ですが、ほとんどの場合はSwagger Editorを用いてスキーマを定義するのが一般的かと思います。これはどんなものかというと、左側でスキーマを編集しながら右側でプレビュー。いわゆる左側でスキーマを定義したものが、リアルタイムでAPIドキュメントとして可視化されて見れるエディタになっています。
また、ほかの選択肢としてStoplight Studioというものがあります。Swaggerとは違って、GUIです。そのため、OpenAPIのスキーマ定義についてあまり詳しくない人でも、ポチポチGUIをいじるだけでスキーマを定義できます。
Swagger Editorの画像は、このようなイメージです。
Stoplight Studioはこんな感じです。実際に触ってみたほうがいいと思います。
続いて、ドキュメントの自動生成ツールについての説明をします。これも知っている方がほとんどかと思いますが、Swagger UIを活用しています。先ほど見せたSwagger Editorのプレビュー側だと思ってもらって問題ありません。スキーマからドキュメントが生成されるので、信頼できます。
続いて、コード生成について見ていきたいと思います。READYFORでは、コード自動生成ツールにOpenAPI Generatorを使用しています。RubyやTypeScriptをサポートしていて、ほかにもJavaやPHPなどもサポートしています。
今回はDockerの例ですが、左の意味としては「openapi.ymlファイルをもとに、src/types/apiディレクトリに生成ファイルを出力する」というコマンドになります。ツリーを見てもらえばわかると思いますが、このように、APIクライアントやモデルが作成されます。
READYFORでは、ジェネレーターとして「typescript-fetch」を使用しています。
実際に生成されたファイルはこんな感じです。APIクライアントや、あとはリクエスト・レスポンスの型が生成されます。
続いて、スキーマから自動で型が生成されるので、リクエストやレスポンスの型にミスがない。いわゆる自前で定義すると、JSONのキーに間違いがあったりなどすると思いますが、そういうのがなくなって、型を信頼できます。
あとは、APIクライアントなどのコードが生成されるので、定型コードを記述するコストも減るんじゃないかなと思います。また、スキーマが変更された際もビルドエラーで修正箇所を把握できるので、おすすめです。
続いて、ハマりどころを紹介したいと思います。まず1点目としては、tagsを指定せずにスキーマを定義すると、APIクラス名が「DefaultApi」 という名前で生成されてしまいます。これを回避するには、ちゃんとtagsを指定しておいたほうがよいです。
続いてハマりどころ2なんですが、operationIdを指定せずにスキーマを定義すると、APIクラスのメソッド名やリクエストデータの型名が自動で生成されてしまいます。これもoperationIdを付与することによって、自分の意図した命名ができるようになります。
ハマりどころ3としては、components/schemasを使用せずにスキーマを定義すると、レスポンスデータの型名というのも自動で生成されるため、「InlineResponseXXX」という感じで、けっこうわかりづらい感じに生成されてしまいます。これも、ちゃんとcomponent/schemaで区切って生成することで、意図した型名で生成できるようになります。
続いて、モックサーバーの活用についてです。モックサーバーを活用することで、APIの実装を待たずにフロント側で開発に着手できるようになります。READYFORでは、Prismというモックサーバーを使用しています。先ほど紹介したStoplight Studioにも、モックサーバーとして統合されています。
コマンドとしてはこんな感じです。openapi.yaml、スキーマをもとにモックサーバーを起動できます。デフォルトでは、毎回同じデータを返すスタティックレスポンスを生成します。一応-dフラグというものがあり、--dynamicオプションを付与することで、毎回異なるデータをレスポンスすることも可能です。
Prismの強力な機能の1つとして、Preferヘッダーを渡すことでレスポンスの変更が可能になります。例えば、コードに対して404のようなステータスコードを付与してあげると、404でレスポンスできるようになるし、さらにスキーマで定義したexampleを指定することによって、そのexampleをレスポンスできるようになります。
あとはdynamicというのがあり、先ほどCLIで紹介した-dオプションと同じダイナミックレスポンスを有効化する機能も、ヘッダーに付与できるようになります。
あとはなにより、Cypressと相性が非常によいです。例えば「入力フォームのsubmitボタンを押して422エラーがレスポンスされたときに、エラーメッセージが表示されるか?」といったテストが簡単にできます。
先ほど紹介したPreferヘッダーを使用してあげることで、これを実現できます。Cypressではリクエストヘッダーをカスマイズできるので、APIにリクエストする前に、ヘッダーをカスタマイズしてリクエストを投げることによって、このエラーレスポンスを返せるようになる、という感じです。
続いて所感についてですが、まずよかったことから説明したいと思います。もうすでに説明していると思いますが、スキーマからAPIドキュメントが生成されるので信頼できます。これはスキーマがメンテナンスされている前提ですが、スキーマファーストに開発していれば信頼できるものになります。
また、TypeScriptのコードが生成されるため、型安全に開発できます。あとは、モックサーバーがかなり強力なので、効率的・テスタブルな開発が可能です。さらに、PR上でOpenAPIのスキーマをベースにバックエンドと認識を合わせられるので、非常に効率的でやりやすいです。
いいところばかりでなくつらいところもあって。これはスキーマ駆動開発というよりは、openapi-generator-cliの問題ですが。CLIによって生成されたコードで、型エラーが発生する場合があります。oneOfやallOfを使用すると、けっこう発生してしまいます。
あえてジェネレータで-gオプションを指定して「typescript-fetch」から「typescript-axios」に変更して試してみました。そうすると、正しいコードが生成できたりするので、改善の余地はありそうだと思っています。
続いて、生成される型が最善ではないところです。enumは、Enum型で出力されます。これは当たり前といえば当たり前なんですが、できればUnion型に出力するオプションが欲しいです。また、nullableなenumをスキーマで定義しても、出力される型としてはnullableになりません。
あとはdate/date-timeフォーマットで指定したものがDate型で出力されます。本来であればstring型にしてほしいところですが、typescript-fetchのみ、そういう感じになってしまいます。
一応--type-mappingsオプションで型をマッピングできるので、これでstring型にはできます。しかし、型が修正されてもAPIクラス側で型エラーが発生するので、ここはフォーマットを指定しない手段をとるしかないかなと思っています。
続いて、スキーマ駆動開発を実践した上で「こういうのを検討したほうがよさそう」ということを記載しています。
まず1点目が「OpenAPI Generatorによって生成されたAPIクライアントを使用するか、それとも型定義のみを使用するか?」です。生成されたAPIクライアントを使うのは非常に効率的ですが、当然それに依存することになります。フロントエンド 側の設計に対応できるかどうか、コードをちゃんと読んで、判断した上で使用するほうがよいかと思います。
続いて、ジェネレータをどれにするかの問題です。そのままtypescript-axiosを使っているならaxiosでもいいとは思いますが、型定義のみ使用する場合は、先に説明した出力される型定義との兼ね合いを見て決定したほうがよさそうだと感じています。
続いて、スキーマ駆動開発を実践してみて重要と感じたことです。これはもうスキーマファーストな上で最も重要だと思いますが、フロントエンドとバックエンドともに、スキーマからコードを生成しましょう、というところです。
仮にですが、フロント側のみスキーマからコードを生成しても、スキーマとAPIの実装に乖離が発生する可能性が高いです。最悪の場合、スキーマがメンテナンスされなくなってしまうので、避けたほうがよいでしょう。
いろいろ紹介しましたが、スキーマ駆動開発は、メリットがデメリットを遥かに上回ると思っています。興味をもった方は、ぜひ実践してみてください。ご清聴、ありがとうございました。
2025.02.13
“最近の新人は報連相をしない”という、管理職の他責思考 部下に対する「NG指示」から見る、認識のズレを防ぐコツ
2025.02.13
AIを使いこなせない人が直面する本当の課題 元マッキンゼー・赤羽雄二氏が“英語の情報”を追い続ける理由
2025.02.06
すかいらーく創業者が、社長を辞めて75歳で再起業したわけ “あえて長居させるコーヒー店”の経営に込めるこだわり
2025.02.12
マネージャーは「プレイング3割」が適切 チームの業績を上げるためのマネジメントと業務の比率
2025.02.14
報連相ができない部下に対するコミュニケーションの取り方 「部下が悪い」で終わらせない、管理職のスキル向上のポイント
2025.02.13
上司からは丸投げ、部下からはハラスメント扱い、業務は増加…プレイングマネジャーを苦しめる「6つの圧力」とは
2025.02.12
何度言っても変わらない人への指示のポイント 相手が主体的に動き出す“お願い”の仕方
2025.02.13
「みんなで決めたから」を言い訳にして仲良しクラブで終わる組織 インパクトも多様性も両立させるソース原理
2025.02.10
32歳で「すかいらーく」を創業、75歳で「高倉町珈琲」で再起業 「失敗したからすかいらーくができた」横川竟氏流の経営哲学
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
着想から2か月でローンチ!爆速で新規事業を立ち上げる方法
2025.01.21 - 2025.01.21
新人の報連相スキルはマネージメントで引きあげろ!~管理職の「他責思考」を排除~
2025.01.29 - 2025.01.29
【手放すTALK LIVE#45】人と組織のポテンシャルが継承されるソース原理 ~人と組織のポテンシャルが花開く「ソース原理」とは~
2024.12.09 - 2024.12.09
『これで採用はうまくいく』著者が語る、今こそ採用担当に届けたい「口説く」力のすべて
2024.11.29 - 2024.11.29
第20回エクゼクティブメンターイベント「今、「ひと」と組織が共創する〜働き方の未来へ」
2024.12.07 - 2024.12.07