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
250
RustでREST_APIを開発した話.pdf
Kyosuke Awata
August 24, 2023
Tweet
Share
More Decks by Kyosuke Awata
See All by Kyosuke Awata
FASTと向き合うことで見えた、大規模アジャイルの難しさと楽しさ / FAST Taught Me Large-Scale Agile Hardships and Fun
wooootack
2
750
(新URLに移行しました)FASTと向き合うことで見えた、大規模アジャイルの難しさと楽しさ
wooootack
0
1k
チーム全員で品質課題の改善のために取り組んだことを振り返る / Quality improvement team reflection
wooootack
4
2.3k
無理せずに みんなで作ろう 発信文化
wooootack
3
2.9k
雰囲気でSWRを使ったらハマった話
wooootack
0
52
マイクロサービスではなくモジュラモノリスを採用した理由
wooootack
4
2.4k
Other Decks in Programming
See All in Programming
ペアプロ × 生成AI 現場での実践と課題について / generative-ai-in-pair-programming
codmoninc
2
20k
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
2
11k
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
3
790
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
710
MCPを使ってイベントソーシングのAIコーディングを効率化する / Streamlining Event Sourcing AI Coding with MCP
tomohisa
0
160
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
310
ソフトウェア品質を数字で捉える技術。事業成長を支えるシステム品質の マネジメント
takuya542
2
14k
CDK引数設計道場100本ノック
badmintoncryer
1
320
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
810
顧客の画像データをテラバイト単位で配信する 画像サーバを WebP にした際に起こった課題と その対応策 ~継続的な取り組みを添えて~
takutakahashi
1
240
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
170
Railsアプリケーションと パフォーマンスチューニング ー 秒間5万リクエストの モバイルオーダーシステムを支える事例 ー Rubyセミナー 大阪
falcon8823
5
1.4k
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
95
14k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
The Language of Interfaces
destraynor
158
25k
Code Reviewing Like a Champion
maltzj
524
40k
How GitHub (no longer) Works
holman
314
140k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Facilitating Awesome Meetings
lara
54
6.5k
Building Adaptive Systems
keathley
43
2.7k
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