Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
NestJSのコードからOpenAPIを自動生成する際の最適解を探す
Search
Tatsuya Asami
March 17, 2025
Programming
0
520
NestJSのコードからOpenAPIを自動生成する際の最適解を探す
Tatsuya Asami
March 17, 2025
Tweet
Share
More Decks by Tatsuya Asami
See All by Tatsuya Asami
終わってる風終わってないタスクが自分の首を締めた話
astatsuya
0
490
Other Decks in Programming
See All in Programming
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
660
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
CSC307 Lecture 05
javiergs
PRO
0
500
MUSUBIXとは
nahisaho
0
140
Fluid Templating in TYPO3 14
s2b
0
130
AIと一緒にレガシーに向き合ってみた
nyafunta9858
0
260
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.4k
フロントエンド開発の勘所 -複数事業を経験して見えた判断軸の違い-
heimusu
7
2.8k
2026年 エンジニアリング自己学習法
yumechi
0
140
組織で育むオブザーバビリティ
ryota_hnk
0
180
「ブロックテーマでは再現できない」は本当か?
inc2734
0
1.1k
AIによる開発の民主化を支える コンテキスト管理のこれまでとこれから
mulyu
3
510
Featured
See All Featured
Practical Orchestrator
shlominoach
191
11k
Rails Girls Zürich Keynote
gr2m
96
14k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
120
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
190
Designing for Performance
lara
610
70k
How STYLIGHT went responsive
nonsquared
100
6k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
0
160
Ethics towards AI in product and experience design
skipperchong
2
200
Un-Boring Meetings
codingconduct
0
200
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.2k
How to Think Like a Performance Engineer
csswizardry
28
2.5k
For a Future-Friendly Web
brad_frost
182
10k
Transcript
© Commune Inc. All rights reserved NestJSのコードから OpenAPIを 自動生成する際の最適解を探す 2024/03/17
NestJS meetup #6 浅見 達也@astatsuya1 1
© Commune Inc. All rights reserved 浅見 達也 (@astatsuya1) •
仕事 ◦ コミューン株式会社 SuccessHub事業部 ▪ 2022年7月~2024年3月 CommuneのWebエンジニア ▪ 2024年4月~ SuccessHubのWebエンジニア • ペット ◦ デグー 自己紹介 2
© Commune Inc. All rights reserved 3 チームの生産性を圧倒的に向上し、カスタマーサクセス組織に成果をもたらす 顧客に関するあらゆる重要な 情報や健康状態を一元管理
テックタッチの工数で ハイタッチの効果を実現 顧客の状態に応じた個別最適な アクションを実行管理
© Commune Inc. All rights reserved • NestJSのコードからOpenAPIを自動生成する際の最適解を探す ◦ これまでやってきて苦戦したことを共有
◦ 道半ばながら辿り着いた最適解を共有 今日の発表内容 4
© Commune Inc. All rights reserved • 技術構成 ◦ バックエンドはNestJS(monorepo,
SWC)でREST API ◦ class-validator, class-transformerを使ってAPIリクエストのバリデーション や変換を行っている ◦ @nestjs/swaggerを使ってソースコードからOpenAPIを出力 ◦ フロントエンド(今回関係ない) ▪ Orvalを使ってOpenAPIからフロントエンドで使用するコード(型定義、データフェッチ、モックサーバー)を 自動生成 ▪ ブラウザからNestJSにHTTPリクエスト(BFFはない) 前提となる技術構成 5
© Commune Inc. All rights reserved 過去やってきたことを紹介します 1. @nestjs/swagger CLI
Pluginの導入をチャレンジ(失敗) a. 実装中にローカルサーバーがエラーで止まりまくる 2. @nestjs/swagger CLI Pluginを使わず、手動でデコレータを付ける(採用) a. 仕組みは出来たが不満あり 今までやってきた OpenAPIの自動生成への取り組み 6
© Commune Inc. All rights reserved ParametersとRequest bodyの出力 4. @nestjs/swagger
CLI Pluginを使わず、手動でデコレータを付ける 7 • リクエストボディ、リクエストパラメータは元々 dtoがあったので、ひたすら @ApiPropertyを つけるのみ • この例は単純だが、他の dtoなどをimportし て型定義に使っている場合はもっと色々記 述する ◦ 結構重要なポイントだが今回は割愛
© Commune Inc. All rights reserved Responseの出力のためにClassSerializerを剥がす 4. @nestjs/swagger CLI
Pluginを使わず、手動でデコレータを付ける 8 • ClassSerializerはクラスインスタ ンスをプレーンオブジェクトに変 換してくれる • 元々エンティティに変換処理のた めのデコレータをつけることがみ んな微妙だと思っていた(コント ローラーで行うべき処理) ので、あまりためらいなく剥がし た
© Commune Inc. All rights reserved Responseの出力のためにdto作成 4. @nestjs/swagger CLI
Pluginを使わず、手動でデコレータを付ける 9 • レスポンスは新たにレスポンス用の dtoを作 成 • レスポンスではバリデーションを行わない ので、OpenAPIのためだけに書いている
© Commune Inc. All rights reserved Response出力のためにコントローラーにデコレータを追加 4. @nestjs/swagger CLI
Pluginを使わず、手動でデコレータを付ける 10 • コントローラーの関数に @ApiOkResponseのデコレータを 追加 ◦ これをつけるとOpenAPIの Responseが出力される • コントローラーの関数の戻り値の型 にdtoを指定することで型安全にす る ◦ dtoにあるプロパティを書き忘 れたらエラーになる
© Commune Inc. All rights reserved 記述が多くて面倒だが、理論上完璧 4. @nestjs/swagger CLI
Pluginを使わず、手動でデコレータを付ける 11
© Commune Inc. All rights reserved • OpenAPIのためのデコレータの記述を間違えがち • 間違っていてもIDE上でエラー等は出ないので、気をつける、ちゃんと確認
する以外のソリューションがない • フロントエンド開発中にミスに気がつくと、バックエンドのコード修正をまず やらないといけないのが面倒 ◦ OpenAPIからフロントエンドのコードを自動生成をしているため、フロ ントエンドの型定義は手動で直せない 半年ほど運用してみて 12
© Commune Inc. All rights reserved かなり単純な記述でも忘れがち 今まで取り組んできたことの流れ 13
© Commune Inc. All rights reserved • @nestjs/swaggerのCLI Plugin導入に再チャレンジ ◦
NestJSのドキュメント通りに実装したところ ▪ 上手く出来ている • ローカルサーバーは動いている • OpenAPIのParameters, Request body, Responseはおおよそ出力されている様 子 ▪ 上手く出来ていない • 12件型エラーが出ている • コード変更しているとたまに型エラーが出る • ローカルサーバーの起動時間が約 3秒→約27秒になった 改善に向けて 14
© Commune Inc. All rights reserved ◦ 全て同じファイルにdtoが複数ある場合だった ▪ 単にファイル分割で対応完了
これでエラーがなくなった! 12件型エラーが出ている 15
© Commune Inc. All rights reserved • ファイル追加や削除、変数名を変更した場合にエラーが出やすい ◦ ローカルサーバーは止まっていないようなのでエラーを無視すれば開発自
体は出来るが気になる • エラー自体が起きないようにするのは難しそう エラーが起きたら復旧出来るようにする コード変更しているとたまに型エラーが出る 16
© Commune Inc. All rights reserved • エラーを起こしているmetadata.tsを上書きする単純なスクリプトを作成 ◦ metadata.tsはCLI
Pluginを使うと生成されるOpenAPIのためのファイル ◦ エラーが起きたらこのスクリプトを実行してリセット スッキリ解決はしてないけど、これでストレスはかなり軽減 コード変更しているとたまに型エラーが出る 17
© Commune Inc. All rights reserved • 流石に許せない ◦ SWCを入れる前と同じくらい時間がかかっている
OpenAPIを立ち上げないコマンドと、OpenAPIを立ち上げるコマンドを用意する ローカルサーバーの起動時間が約 3秒→約27秒になった 18
© Commune Inc. All rights reserved • OpenAPIを生成するときとしないときのnest-cliを作成 ◦ nest-cli.json(しない)とnest-cli-openapi.json(する)を作成
◦ コマンド実行時にファイルパスを指定する ローカルサーバーの起動時間が約 3秒→約27秒になった 19 SwaggerModule
© Commune Inc. All rights reserved • OpenAPIを使わない場合はSwaggerModuleも読み込まない ◦ metadata.tsを読み込まなければ速度はあまり変わらないが、不完全な
OpenAPIが見たいこと はない、混乱の元なので全部読み込まない • npm scripts(コマンド長い) ローカルサーバーの起動時間が約 3秒→約27秒になった 20 SwaggerModule
© Commune Inc. All rights reserved コマンドの使い分け • 普段のバックエンド開発では OpenAPIは生成しないで立ち上げ
◦ バックエンド開発中は OpenAPIをあまり見ないため ◦ ローカルサーバーは安定して欲しい、何度も起動するので速度も重要 • OpenAPIを見たい時、変更するときは OpenAPIを生成して立ち上げ ◦ 実装中にエラーが出たときはリセットコマンドで回避可能 ◦ プロダクションビルド (nest build)も遅くなるが、サーバーの起動速度はほぼ変わらなかったの で問題なし 少し苦しいがなんとか課題解決! ローカルサーバーの起動時間が約 3秒→約27秒になった 21 SwaggerModule
© Commune Inc. All rights reserved • dtoにあるOpenAPIには不要なプロパティに @ApiHidePropertyをつけていく ◦
toNameのような変換関数が主に不要な値 • 不要になった@ApiPropertyを消していく ◦ あっても問題ない。@ApiPropertyに記述してある値 が優先的に使われる ◦ 型定義が複雑な場合は引き続き指定する必要があ る 残りの作業は @ApiHidePropertyをつけていく 22
© Commune Inc. All rights reserved これで一通り完了! 23
© Commune Inc. All rights reserved ◦ dtoは1ファイルに1つのみ記載する ◦ dtoの各プロパティには基本的に@ApiPropertyをつけない。上手く出力されな
い場合にのみ@ApiPropertyを使って正しい値を自分で記述する ◦ dtoにあるOpenAPIには出力したくないプロパティには@ApiHidePropertyをつ ける 開発時に気にすることまとめ 24
© Commune Inc. All rights reserved • OpenAPIのために技術的な選択が必要だった ◦ ClassSerializerを剥がしたが、剥がしたくない場合は積んでいたかも
• コードからドキュメント(OpenAPI)が自動生成される一番嬉しい状態が作れた • 快適なローカル開発環境との両立は許容できる 総じて満足 道半ばながら辿り着いた最適解振り返り 25
© Commune Inc. All rights reserved NestJSとOpenAPIの話は以上です 最後に本件と関係ないけど気になっていること 26
© Commune Inc. All rights reserved • NestJSでそこまでコード量が多くないのにモジュールの読み込みに結構時間が かかるのをどう対処しているのか •
漏れがなく、負荷が少ない操作ログの設計 • MySQL, Prismaを使ってマルチテナントの実装する場合の工夫 • Visual Regression Testで何をどこまで確認しているか この後の懇親会で相談させてください!! 最後に本件と関係ないけど気になっていること 27
募集中の求⼈はこちら カジュアル⾯談も 実施しています! コミューン株式会社では共に働く仲間を募集中です ありがとうございました