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.2k
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
320
Rustソースコードのざっくりとした歩き方 🦀
tako8ki
14
6.3k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
510
How to contribute to Rust and what I have recently been working on
tako8ki
0
260
RustでTUIのSQLクライアントを作った
tako8ki
0
1.2k
A Ruby version manager written in Rust, which is 7 seconds faster than rbenv
tako8ki
1
1.7k
Other Decks in Technology
See All in Technology
Amazon SageMaker Unified Studio(Preview)、Lakehouse と Amazon S3 Tables
ishikawa_satoru
0
150
Storage Browser for Amazon S3
miu_crescent
1
180
祝!Iceberg祭開幕!re:Invent 2024データレイク関連アップデート10分総ざらい
kniino
3
290
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
170
多領域インシデントマネジメントへの挑戦:ハードウェアとソフトウェアの融合が生む課題/Challenge to multidisciplinary incident management: Issues created by the fusion of hardware and software
bitkey
PRO
2
110
KubeCon NA 2024 Recap: How to Move from Ingress to Gateway API with Minimal Hassle
ysakotch
0
200
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
190
コンテナセキュリティのためのLandlock入門
nullpo_head
2
320
AI時代のデータセンターネットワーク
lycorptech_jp
PRO
1
290
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
280
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
130
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
160
Featured
See All Featured
Producing Creativity
orderedlist
PRO
341
39k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Typedesign – Prime Four
hannesfritz
40
2.4k
Code Reviewing Like a Champion
maltzj
520
39k
Optimizing for Happiness
mojombo
376
70k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Scaling GitHub
holman
458
140k
Gamification - CAS2011
davidbonilla
80
5.1k
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