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でREST_APIを開発した話.pdf
Search
Kyosuke Awata
August 24, 2023
Programming
0
220
RustでREST_APIを開発した話.pdf
Kyosuke Awata
August 24, 2023
Tweet
Share
More Decks by Kyosuke Awata
See All by Kyosuke Awata
雰囲気でSWRを使ったらハマった話
wooootack
0
24
マイクロサービスではなくモジュラモノリスを採用した理由
wooootack
4
2.1k
Other Decks in Programming
See All in Programming
Remix on Hono on Cloudflare Workers
yusukebe
1
300
CSC509 Lecture 11
javiergs
PRO
0
180
A Journey of Contribution and Collaboration in Open Source
ivargrimstad
0
950
イベント駆動で成長して委員会
happymana
1
330
役立つログに取り組もう
irof
28
9.6k
よくできたテンプレート言語として TypeScript + JSX を利用する試み / Using TypeScript + JSX outside of Web Frontend #TSKaigiKansai
izumin5210
6
1.7k
Micro Frontends Unmasked Opportunities, Challenges, Alternatives
manfredsteyer
PRO
0
100
as(型アサーション)を書く前にできること
marokanatani
10
2.7k
Jakarta EE meets AI
ivargrimstad
0
650
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
630
エンジニアとして関わる要件と仕様(公開用)
murabayashi
0
300
Featured
See All Featured
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Navigating Team Friction
lara
183
14k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Keith and Marios Guide to Fast Websites
keithpitt
409
22k
Typedesign – Prime Four
hannesfritz
40
2.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
How GitHub (no longer) Works
holman
310
140k
Git: the NoSQL Database
bkeepers
PRO
427
64k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
A designer walks into a library…
pauljervisheath
204
24k
Transcript
RustでREST APIを開発した話
名前 粟⽥ 恭介(@wooootack) 経歴 2019年に異業種からエンジニアに転職し、2021年にプラハに⼊社。 仕事内容 フルサイクルエンジニアとしてプロダクト開発全般に従事。 約1年前からチームリーダーとして、マネジメントにも挑戦中。 趣味 ⾞(写真は愛⾞)、アイドルヲタク(歴⻑め)、ぷよテト(テトリス勢)
⾃⼰紹介
はじめに • Zennに書いたこちらの記事からRustの技術的な部分に関連する内容を抜粋し てお話しします。 ◦ 記事を書いたのが約半年前なので、最新情報に追従できていない可能性があります :bow: • 今⽇はREST APIを開発してみて得られた知⾒や感想を話します
◦ どうやって開発するかは話しません :bow: • サンプルリポジトリはこちら
使⽤技術 / 設計思想 使⽤技術 • Rust(1.64.0) • actix-web(4.1.0) • diesel(2.0.0)
設計思想 • DDD • オニオンアーキテクチャ • モジュラモノリス
ディレクトリ構造 • bin ◦ エントリーポイントとなるファイルを置く ◦ api.rs -> APIサーバー起動時のエントリーポイント ◦
seed.rs -> シードデータ投⼊時のエントリーポイント • modules/ ◦ 後述 • scenarios/ ◦ エンドポイントと1:1で紐づくシナリオを定義 ◦ 各モジュールを使って処理を⾏う ◦ オーケストレータ的な役割 • routers.rs ◦ RESTAPIのルーティング定義 • schema.rs ◦ dieselが⾃動⽣成するschemaファイル
ディレクトリ構造 • modules/common ◦ 共通処理の定義。エラー定義などが該当する。 • modules/diesel ◦ dieselの処理は複数モジュールで呼び出されるのでここに置く •
modules/user ◦ 単体のRESTAPIとして動かせるようにレイヤー分け ◦ DDD+オニオンアーキテクチャに従っている • modules/task ◦ userと同じなので省略
良かったところ 1. モジュールの可視性を細かく設定できる 2. エラーハンドリングを簡略化できる
1. モジュールの可視性を細かく設定できる • モジュールそのものをpublic/privateに宣⾔できる ◦ 内部で間違えてpublicにしてしまって外部に公開されるみたいなことを防げる • struct, fnごとにpublic/privateに宣⾔できる ◦
同じモジュール内でも呼ばせたくないみたいなこともできる • pub(crate), pub(super) のような構⽂がある ◦ どこまで公開するかを細かく設定できる 参考 • https://doc.rust-jp.rs/rust-by-example-ja/mod.html
実際の例 - モジュール単位の可視性の設定 各モジュールはpresentation層のみを 外部に公開することで疎結合に保たれている
良かったところ 1. モジュールの可視性を細かく設定できる 2. エラーハンドリングを簡略化できる
2. エラーハンドリングを簡略化できる • Result + ? + Fromトレイトを使えば、エラーハンドリングが楽になる ◦ エラーの詰め替え作業が激減
◦ match式でOkかErrかを判定して〜みたいなコードが消えて読みやすくなる 参考 • https://doc.rust-jp.rs/rust-by-example-ja/error/result.html
実際の例 - Fromトレイトの実装① 発⽣する全てのエラーがApiErrorに変換されるようにFromトレイトを実装
ApiErrorにはactix-webのResponseErrorトレイトを実装することで APIサーバーのResponseとして返せるように 実際の例 - Fromトレイトの実装②
実際の例 - 簡略化されたエラーハンドリング • ?演算⼦を書くだけで良くなる • 例:リポジトリでDieselErrorが発⽣ ◦ DomainError ◦
↓ ◦ UsecaseError ◦ ↓ ◦ ApiError ◦ ↓ ◦ Response(status_code: 500) • 他の層も同様にエラーは全部?でOK ↑(例)scenario層のコード
苦労したところ 1. 可変参照の扱いが(場合によっては)難しい 2. エコシステムが(まだ)充実していない
1. 可変参照の扱いが(場合によっては)難しい • Rustの可変参照は安全性を担保するために多くの制約がある ◦ 複数箇所から同時に参照できない ◦ データを変更できない など... •
今回の作りでは、scenario層でDBのトランザクションを管理する ◦ dieselでtransaction貼った時のコネクションオブジェクトは 可変参照 ◦ これを複数の場所に渡す必要が⽣まれてしまい、実装できなかった 参考 • https://doc.rust-jp.rs/book-ja/ch04-02-references-and-borrowing.html
実際の例 - トランザクションを張らない実装 (ツッコみどころはあると思いますが) • conn を1箇所にしか渡さないのでOK • outpuddingはasyncの戻り値の型を明 ⽰するための記述
◦ 詳細はこちら参照
実際の例 - トランザクションを張る実装 • こちらはコンパイルエラーになります • txは &mut なコネクションであるた め、execute関数の引数に2度渡されて
しまうことでエラーになっています • これをうまく解決する⼿段を私は⾒つ けられませんでした...
苦労したところ 1. 可変参照の扱いが(場合によっては)難しい 2. エコシステムが(まだ)充実していない
2. エコシステムが(まだ)充実していない • テストを書く時の良いライブラリがない ◦ Jestが恋しくなりました ... ◦ 単体テストならそこまで問題にならないが、統合テストを書く時に困った ◦
特に統合テストにおいては、セットアップ関数やクリーンアップ関数などを動かしたい • VSCodeで書いてるとマクロの内容までは理解してくれずに、型補完が効かな い時があった ◦ ビルドは通るけど、エディタ上では型が分からないみたいな ◦ 当時の話なので、今はさらに進化していると信じたい
実際の例 - テストを書く際に⼯夫したこと • 単体テストと統合テストを分けて動かせるようにした ◦ 標準のテスト機能とフィーチャーフラグ機能を使って実現した 参考 • https://doc.rust-jp.rs/book-ja/ch11-01-writing-tests.html
• https://doc.rust-lang.org/cargo/reference/features.html
実際の例 - テストを書く際に⼯夫したこと これは結構簡単にできます • Cargo.tomlにfeaturesを定義 • 統合テストを書く時は、featuresを指定 • cargo
test --feaures integration_test
気を付けた⽅が良さそうなところ • 構造体に参照を保持させると⼀気に難しくなるので、避けた⽅が無難 ◦ ただリポジトリはコネクションを持っておきたいなど、必要な場⾯もありそう • 特にテスト周りはまだ不便に感じる部分が多いかも • PrismaやActiveRecordレベルのORMはまだ存在しない(と思う)
まとめ RustでAPI開発、ありだと思います
We are Hiring 株式会社プラハの応募はこちらから ぜひ⼀緒に、ものづくりを楽しみましょう! 頭の中にしかないアイデアを形にしていく「ものづくり」はすごく楽しいことです。 しかし学ぶべきことも数多くあり、難しい局⾯に⽴ち向かうことも多々あることでしょう。 そんな時、⼀緒に切磋琢磨できる仲間が集まっていれば、どんな挑戦にも楽しく挑めるのではないでしょうか。 そのような素晴らしい環境で「ものづくり」をしたいと感じてくれた⽅がいましたら、ぜひお声がけください! 株式会社アガルートテクノロジーズの応募はこちらから
https://tech.agaroot.co.jp/#recruit https://www.praha-inc.com/recruit