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.6k
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
480
Rustソースコードのざっくりとした歩き方 🦀
tako8ki
14
6.6k
簡単なシェルを作ってRustを学ぼう
tako8ki
1
600
How to contribute to Rust and what I have recently been working on
tako8ki
0
320
RustでTUIのSQLクライアントを作った
tako8ki
0
1.4k
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
「実体」で築く共通認識: 開発現場のコミュニケーション最適化 / Let's Get on the Same Page with Concrete Artifacts: Optimization of Communication in dev teams
kazizi55
0
150
TODAY 看世界(?) 是我們在看扣啦!
line_developers_tw
PRO
0
490
API の仕様から紐解く「MCP 入門」 ~MCP の「コンテキスト」って何だ?~
cdataj
0
170
vLLM meetup Tokyo
jpishikawa
1
250
DB 醬,嗨!哪泥嘎斯基?
line_developers_tw
PRO
0
490
2025/6/21 日本学術会議公開シンポジウム発表資料
keisuke198619
2
430
OCI Oracle Database Services新機能アップデート(2025/03-2025/05)
oracle4engineer
PRO
1
190
VISITS_AIIoTビジネス共創ラボ登壇資料.pdf
iotcomjpadmin
0
120
Devin(Deep) Wiki/Searchの活用で変わる開発の世界観/devin-wiki-search-impact
tomoki10
0
710
活きてなかったデータを活かしてみた話 / Shirokane Kougyou vol 19
sansan_randd
1
380
Model Mondays S2E01: Advanced Reasoning
nitya
0
420
工具人的一生: 開發很多 AI 工具讓我 慵懶過一生
line_developers_tw
PRO
0
470
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
107
19k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
GraphQLとの向き合い方2022年版
quramy
46
14k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
The World Runs on Bad Software
bkeepers
PRO
68
11k
KATA
mclloyd
29
14k
A Tale of Four Properties
chriscoyier
159
23k
Code Review Best Practice
trishagee
68
18k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Designing for humans not robots
tammielis
253
25k
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