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
1
2.7k
Rustで始めるコードファーストなOpenAPI定義の生成 🦀
Rust、何もわからない... #9
https://estie.connpass.com/event/289216/
TaKO8Ki
July 26, 2023
Tweet
Share
More Decks by TaKO8Ki
See All by TaKO8Ki
RustのReturn-position impl trait in trait (RPITIT) の実装を雑に見てみる
tako8ki
1
520
Rustソースコードのざっくりとした歩き方 🦀
tako8ki
14
6.7k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
630
How to contribute to Rust and what I have recently been working on
tako8ki
0
340
RustでTUIのSQLクライアントを作った
tako8ki
0
1.4k
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
JTCにおける内製×スクラム開発への挑戦〜内製化率95%達成の舞台裏/JTC's challenge of in-house development with Scrum
aeonpeople
0
270
「その開発、認知負荷高すぎませんか?」Platform Engineeringで始める開発者体験カイゼン術
sansantech
PRO
2
790
OCI Oracle Database Services新機能アップデート(2025/06-2025/08)
oracle4engineer
PRO
0
180
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
350
20250912_RPALT_データを集める→とっ散らかる問題_Obsidian紹介
ratsbane666
0
100
Codeful Serverless / 一人運用でもやり抜く力
_kensh
7
450
Apache Spark もくもく会
taka_aki
0
140
「Linux」という言葉が指すもの
sat
PRO
4
140
2025/09/16 仕様駆動開発とAI-DLCが導くAI駆動開発の新フェーズ
masahiro_okamura
0
130
まずはマネコンでちゃちゃっと作ってから、それをCDKにしてみよか。
yamada_r
2
120
Snowflake×dbtを用いたテレシーのデータ基盤のこれまでとこれから
sagara
0
120
初めてAWSを使うときのセキュリティ覚書〜初心者支部編〜
cmusudakeisuke
1
280
Featured
See All Featured
The Pragmatic Product Professional
lauravandoore
36
6.9k
How to Ace a Technical Interview
jacobian
279
23k
Agile that works and the tools we love
rasmusluckow
330
21k
Mobile First: as difficult as doing things right
swwweet
224
9.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
GraphQLとの向き合い方2022年版
quramy
49
14k
How to train your dragon (web standard)
notwaldorf
96
6.2k
Documentation Writing (for coders)
carmenintech
74
5k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
850
Statistics for Hackers
jakevdp
799
220k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
A Modern Web Designer's Workflow
chriscoyier
696
190k
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