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
Rustで始めるコードファーストなOpenAPI定義の生成 🦀
Search
TaKO8Ki
July 26, 2023
Technology
3.1k
1
Share
Rustで始めるコードファーストなOpenAPI定義の生成 🦀
Rust、何もわからない... #9
https://estie.connpass.com/event/289216/
TaKO8Ki
July 26, 2023
More Decks by TaKO8Ki
See All by TaKO8Ki
RustのReturn-position impl trait in trait (RPITIT) の実装を雑に見てみる
tako8ki
1
1k
Rustソースコードのざっくりとした歩き方 🦀
tako8ki
14
7k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
710
How to contribute to Rust and what I have recently been working on
tako8ki
0
400
RustでTUIのSQLクライアントを作った
tako8ki
0
1.5k
A Ruby version manager written in Rust, which is 7 seconds faster than rbenv
tako8ki
1
1.8k
Other Decks in Technology
See All in Technology
エージェントスキルを作って自分のインプットに役立てよう
tsubakimoto_s
0
320
AIを共同作業者にして書籍を執筆する方法 / How to Write a Book with AI as a Co-Creator
ama_ch
2
130
みんなの「データ活用」を支えるストレージ担当から持ち込むAWS活用/コミュニティー設計TIPS 10選~「作れる」より、「続けられる」設計へ~
yoshiki0705
0
250
基盤を育てる 外部SaaS連携の運用
gamonges_dresscode
1
120
明日からドヤれる!超マニアックなAWSセキュリティTips10連発 / 10 Ultra-Niche AWS Security Tips
yuj1osm
0
580
Azure Static Web Apps の自動ビルドがタイムアウトしやすくなった状況に対応した件/global-azure2026
thara0402
0
400
AWS Agent Registry の基礎・概要を理解する/aws-agent-registry-intro
ren8k
3
370
AIが書いたコードを信じられない問題 〜レビュー負荷を下げるために変えたこと〜 / The AI Code Trust Gap: Reducing the Review Burden
bitkey
PRO
6
1.3k
Claude Code を安全に使おう勉強会 / Claude Code Security Basics
masahirokawahara
11
31k
Standards et agents IA : un tour d’horizon de MCP, A2A, ADK et plus encore
glaforge
0
160
Eight Engineering Unit 紹介資料
sansan33
PRO
3
7.3k
小説執筆のハーネスエンジニアリング
yoshitetsu
0
670
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.9k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.3k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
99
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.6k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
770
Context Engineering - Making Every Token Count
addyosmani
9
830
Automating Front-end Workflow
addyosmani
1370
200k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
330
Skip the Path - Find Your Career Trail
mkilby
1
110
Agile that works and the tools we love
rasmusluckow
331
21k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
Rustで始めるコードファーストな OpenAPI定義の生成 🦀 Takayuki Maeda / TaKO8Ki
• Rust committer (member of compiler contributors team and diagnostic
working group) • Software Engineer @Moneyforward Takayuki Maeda / TaKO8Ki @TaKO8Ki @TaKOBKi
何を作っているか?
何を作っているか? ref: https://corp.moneyforward.com/news/release/service/20230216-mf-press/
何を作っているか? 国際規格「Peppol(ペポル)」とは、受発注や請求にかかる電子文書をネットワーク上で やり取りするための「文書仕様」「ネットワーク」「運用ルール」の規格で、国際的な非営 利組織であるOPEN PEPPOLが管理しているグローバルな標準規格
What is Peppol? ref: Introduction to Peppol AS4 12
What is Peppol? ref: Introduction to Peppol AS4 12 電子文書はXMLでやり取りされ
る
What is Peppol?
What is Peppol?
What is Peppol?
何を作っているか? 自分がいるチームではこのSMPとAccess Pointのラッパー・請求書のvalidatorである Peppol APIをRustで開発している。
コードファーストな OpenAPI定義の生成を したい
コードファーストなOpenAPI定義の生成をしたい Peppol APIはマネーフォワードの各プロダクトで利用されるマイクロサービスなので、 RESTful APIのインターフェイスを定義したい。
コードファーストなOpenAPI定義の生成をしたい Peppol APIはマネーフォワードの各プロダクトで利用されるマイクロサービスなので、 RESTful APIのインターフェイスを定義したい。加えてできるだけ実装と対応した定義に したい。
Invoice XML is complicated and has “161” elements and some
attributes. コードからOpenAPI documentationを生成し たい
コードファーストなOpenAPI定義の生成をしたい そこで便利なのが utoipa というcrate utoipa - Simple, Fast, Code first
and Compile time generated OpenAPI documentation for Rust
例えばこんな感じでattributeを使ってpathを定義できる
例えばこんな感じでattributeを使ってpathを定義できる
こんな感じでderiveを使ってschemaを定義できる
こんな感じでderiveを使ってschemaを定義できる
Doc用のstructをOpenApi deriveをつけて定義して、
Documentation用のstructをOpenApi deriveをつけて定義して、
こんな感じで定義を出力できます
もしくは、こんな感じでroutingを設定すると/swagger-uiでSwagger UIが見 られる
コードファーストなOpenAPI定義の生成をしたい 総じてすごく使いやすい。特にstructにattributeとしてdescriptionやexampleを書け るのがメンテナンスしやすくて良い。
コードファーストなOpenAPI定義の生成をしたい ただ気をつけないといけないこともある。
コードファーストなOpenAPI定義の生成をしたい 例えば、utoipaでは、$refでスキーマなどにアクセス可能かどうかは自分達で担保する必要が ある。 > Note! Utoipa does not guarantee
that free form ref is accessbile via OpenAPI doc or Swagger UI, users are eligible to make these guarantees. ref: https://docs.rs/utoipa/latest/utoipa/attr.path.html#request-body-attributes
どういうことかというと、例えばこれは、
こうなって、
Tagをschemasに追加し忘れると存在しないschemaを参照してしまう
また例えば定義されていない型をbodyとして指定すると、
普通にコンパイルが通り、refになってしまう
コードファーストなOpenAPI定義の生成をしたい ToSchema derive、path attributeでは、ユーザーが定義したものについてはrefで参 照するような実装になっている。つまり、すごく大きなStructなどを扱う時に全ての Struct・Enumをschemaとして追加しないといけない?
壊れにくいOpenAPI 定義を作るために
壊れにくいOpenAPI定義を作るために まず、新しいpathやschemaを追加した時に、存在しないschemaを参照してOpenAPI 定義が壊れにくいようにしたい。
そんな時に使えるのが #[schema(inlline)]。これをもとに定義を作ると、
こんな感じでtagがinline化される
壊れにくいOpenAPI定義を作るために これによって存在しないスキーマを参照することを防げる。 ただ個人的にはデフォルトがinlineでrefにしたい時だけ#[schema(ref)]にするみたい な実装の方がユーザ的には使いやすいんじゃないかと思う。結構大きな変更なのでプ ルリク投げるか難しいところ。
壊れにくいOpenAPI定義を作るために 次に、定義してない型を指定した時にコンパイルエラーになって欲しい。
これも同じようにpathでinlineを使うことで一応防げる。 下記はコンパイルエラーになる。
壊れにくいOpenAPI定義を作るために 本当はinline無しでも定義してない型はコンパイルエラーになって欲しい。
Invoice XML is complicated and has “161” elements and some
attributes. じゃあなぜこういう実装になってるのか?
Invoice XML is complicated and has “161” elements and some
attributes. ここで少し実装を覗いてみる
壊れにくいOpenAPI定義を作るために まず、 cargo-expand でpathがどういうコードを生成するのか覗いてみる。
None
None
None
utoipa-gen/src/component.rs:746:759
utoipa-gen/src/component.rs:746:759 受け取ったpathをstringに そのnameを渡しているのでコンパイルエラーにな らない。
Invoice XML is complicated and has “161” elements and some
attributes. じゃあinlineの時はどうなってるか?
utoipa-gen/src/component.rs:726:740 type_pathがstringに変換されずにそのまま 使われている
utoipa-gen/src/component.rs:726:740 type_pathがstringに変換されずにそのまま 使われている じゃあこれをnot inlineでも実現すればいいのでは?
壊れにくいOpenAPI定義を作るために 色々みるとpathのbodyなどには定義された型以外も渡ってくることが判明した。
asを使って代替pathを設定でき、これがbodyとして使える。
asを使って代替pathを設定でき、これがbodyとして使える このケースでコンパイルエラーになってはいけない
壊れにくいOpenAPI定義を作るために 最終的にbodyに定義されていない型が来たときにコンパイルエラーにする実装を途中 まで書いていたところでこれに気づいて断念した。
Invoice XML is complicated and has “161” elements and some
attributes. 元の話に戻ります
壊れにくいOpenAPI定義を作るために 壊れにくいOpenAPI定義を作るためにというか、openapi.yamlと実装に差分が出ない ように別クレートを作ってunit testをその中に含めている。
コードから生成したものと実際の openapi.ymlに差分 があるかチェックし、あれば更新を促している。
まとめ
© Money Forward, Inc. まとめ • Rustでは、utoipaを使ってコードファーストなOpenAPI定義の生成ができ る。 • utoipaは気をつけるべきポイントはあるが、総じて使いやすい。
• 疑問点があったら実装を覗いてみて改善点があればパッチを投げてみる のが良さそう。 自分は最終的にtypo修正だけして終わりました。 https://github.com/juhaku/utoipa/pull/669
Invoice XML is complicated and has “161” elements and some
attributes. We are hiring!
None