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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
TaKO8Ki
July 26, 2023
Technology
3.2k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
1.1k
Rustソースコードのざっくりとした歩き方 🦀
tako8ki
14
7.2k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
740
How to contribute to Rust and what I have recently been working on
tako8ki
0
450
RustでTUIのSQLクライアントを作った
tako8ki
0
1.6k
A Ruby version manager written in Rust, which is 7 seconds faster than rbenv
tako8ki
1
1.9k
Other Decks in Technology
See All in Technology
[potatotips #96] Give Your AI Agent the Flutter Playbook
korodroid
0
110
老害フォレンジッカーはAI羊の夢を見るか?
tadmaddad
0
350
トヨタ⽣産⽅式(TPS)⼊⾨
recruitengineers
PRO
3
1.1k
現場回帰したデータエンジニアが考える AI 時代のキャリア開発 / Career Development in the Age of AI Perspectives from a Hands-on Data Engineer
medley
0
260
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
250
Genie Codeハンズオン応用編
taka_aki
0
130
2026-08-15 JAWS-UG 茨城 #16 Secrets ManagerにおけるSecret値の管理(Terraformの場合) / Secrets Manager Secrets
masasuzu
0
350
事業価値と Engineering 2026年度版
recruitengineers
PRO
51
25k
まちスペース®とデジタルツインと「まちづくり」
hiro_ogi
0
130
なぜ Temporal の大小比較には compare しかないのか / Why Does Temporal Only Have compare() for Comparisons
kazukihayase
1
180
AI時代に、人は何を、どう学ぶのか #pbl_pub / What and How Do We Learn in the AI Era?
takaking22
1
140
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Spectacular Lies of Maps
axbom
PRO
1
930
So, you think you're a good person
axbom
PRO
2
2.1k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
Producing Creativity
orderedlist
PRO
348
40k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
290
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
KATA
mclloyd
PRO
35
15k
Documentation Writing (for coders)
carmenintech
77
5.5k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.5k
We Have a Design System, Now What?
morganepeng
55
8.3k
Designing for Timeless Needs
cassininazir
1
450
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