Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
一休.comレストランのRustバックエンド開発の様子
Search
Kōhei Yamamoto (山本浩平)
February 28, 2024
Programming
12k
15
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
一休.comレストランのRustバックエンド開発の様子
Rust、何もわからない... #12
の発表資料です
Kōhei Yamamoto (山本浩平)
February 28, 2024
More Decks by Kōhei Yamamoto (山本浩平)
See All by Kōhei Yamamoto (山本浩平)
総会員数1,500万人のレストランWeb予約サービスにおけるRustの活用
kymmt90
3
3.6k
一休.comレストランにおけるRustの活用
kymmt90
3
1.2k
レガシーWebアプリケーションの性能とコードの健全性をインクリメンタルに改善する / pepabotech-20211209
kymmt90
1
3.1k
コードレビュー座学 / About code reviews
kymmt90
0
6.9k
ペパボのWebサービス 開発スタイル / Web services development at GMO Pepabo
kymmt90
2
640
GraphQL and Schema-First Development
kymmt90
4
4.2k
EC新サービスにおけるスキーマファースト開発 / Schema First Development in the New EC Service
kymmt90
1
2.5k
rails new --api してからやったこと 〜2017年・夏〜 / EC Tech MTG 3
kymmt90
0
940
カテゴリ階層の拡張を目的とした階層的トピックモデル / A hierarchical topic model for expanding category hierarchies
kymmt90
0
650
Other Decks in Programming
See All in Programming
The Rails Doctrine Decade
koic
2
390
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
160
すこし踏み込む CancellationToken
htkym
2
1.1k
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
200
Jetpack Compose メカニズム
skydoves
0
480
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
270
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
2
300
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
290
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
130
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
320
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.3k
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
300
Featured
See All Featured
Ethics towards AI in product and experience design
skipperchong
2
380
Statistics for Hackers
jakevdp
799
230k
Facilitating Awesome Meetings
lara
57
7.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
260
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Building Adaptive Systems
keathley
44
3.2k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
540
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
520
Transcript
0 Rust、何もわからない… #12 一休.comレストランの Rustバックエンド開発の様子 2024-02-28 山本浩平
1 自己紹介 • 山本浩平 (kymmt, @kymmt90) • 一休.comレストランのエンジニア ◦ 一休には2023年9月末に入社し、
一休.comレストランのRustでの開発に参加 • Rust歴は半年強
2 一休とRust | 一休.comレストランとは • 上質なレストランをスムーズに 予約できるサービス https://restaurant.ikyu.com
3 一休とRust | Rustを利用している箇所 • スマートフォンビューにおけるGraphQLバックエンド ◦ 従来のPythonバックエンドを一部置き換え ◦ 2023-10から本番で運用
◦ レストランの詳細や空席の閲覧から予約完了まで • 社内のマイクロサービスと通信するためのREST API ◦ まだ少ない
4 一休とRust | Rustを選定した狙い • CPU利用効率の向上に伴うパフォーマンスの改善 ◦ CVRに直結するレスポンス高速化 ◦ クラウドの利用コストを削減
• 開発生産性の向上 ◦ 型や便利な機能でドメインロジックを実装 • 組織の技術ポートフォリオの多様性を維持 ◦ 古くからある.NET系、近年増えたGoが大半だった ところにRustが!
5 一休.comレストランにおける Rust活用の様子を紹介します 🦀
6 1. Cargo Workspaceでcrate依存関係制御 • 現在のモジュール構造 ◦ CQRSに基づいて 細かくcrateを分けている
7 1. Cargo Workspaceでcrate依存関係制御 • Cargo Workspace ◦ プロジェクトで複数のcrateを管理できる ◦
各crateのCargo.tomlで依存する他のcrateを指定する • 依存関係を変更したいとき ◦ Cargo.tomlが変更されるのでレビューで確認できる ◦ うっかり変な方向の依存が入ったりしにくい ドメインモデル層 データアクセス層 OK! ?
8 1. Cargo Workspaceでcrate依存関係制御 # ルートディレクトリのCargo.toml [workspace] resolver = "2"
members = [ "backend/*", ] [workspace.dependencies] backend-query-model = { path = "./backend/query-model" } # ... 各crateをworkspaceのmemberにする (この例ではbackendディレクトリ配下) workspaceのmemberが backend-query-modelとして ./backend/query-model に依存できるようルートで設定する
9 1. Cargo Workspaceでcrate依存関係制御 # データアクセス層のCargo.toml [package] name = "backend-data-access"
version.workspace = true authors.workspace = true edition.workspace = true publish.workspace = true [dependencies] backend-query-model = { workspace = true } workspace.dependencies で設定した特定のcrateへの 依存をCargo.tomlに明記する
10 2. 便利なツールでコードの質をチェック • rustfmt (cargo fmt)でフォーマットし忘れをチェック ◦ cargo fmt
--all -- --check • Clippy (cargo clippy)で望ましくない書きかたをチェック ◦ cargo clippy --all-targets --all-features -- -D warnings • cargo-nextestで自動テストを実行 ◦ よりCIに向いたテストランナー ◦ cargo nextest run
11 3. 型安全なデータ変換 • Webバックエンドではデータ変換が頻出 ◦ データストアの生データ ↔ DTO ◦
DTO ↔ クエリモデルのインスタンス ◦ クエリモデルのインスタンス ↔ HTTPのレスポンス • 一休.comレストランの場合 ◦ DBや検索サーバからのデータが最終的にGraphQLの レスポンスに
12 3. 型安全なデータ変換 | Serde • Serde/serde_asを生データからDTOへのデシリアライズで 利用 ◦ 属性マクロ(アノテーションのようなもの)を書いて
生データとDTOの属性をマッピング
13 3. 型安全なデータ変換 | Serde mod dto { // ...
#[serde_with::serde_as] #[derive(Debug, serde::Deserialize)] pub struct Restaurant { #[serde(rename = "restaurant_id")] #[serde_as(as = "serde_with::TryFromInto<i32>")] id: RestaurantId, #[serde(rename = "restaurant_name")] name: String, // ... } } • カラム名と属性名 • 整数値と値オブジェクト のマッピングを定義して 型安全にレストランの データをデシリアライズ
14 3. 型安全なデータ変換 | From/TryFrom • std::convertのトレイト FromやTryFromをRust上の データの変換に利用 •
Fromを実装してDTOからモデルへの変換方法を定義 ◦ 例: impl From<dto::Restaurant> for query_model::Restaurant ◦ Intoも自動的に実装される ▪ ブランケット実装 impl<T, U> Into<U> for T where U: From<T> ◦ from/intoでDTO ↔ モデルを型安全に変換できる
15 3. 型安全なデータ変換 | From/TryFrom // Fromを実装するとブランケット実装によりIntoも自動的に実装 impl From<dto::Restaurant> for
query_model::Restaurant { fn from(d: dto::Restaurant) -> Self { Self { id: d.id, name: d.name, // ... } } } // 相互に変換可能 let model: query_model::Restaurant = dto.into(); let dto = dto::Restaurant::from(model); 型推論が効くので 個別の型注釈は不要な ことも多い
16 4. Webアプリ開発に便利なcrateを活用 • GraphQLサーバの実装にはasync-graphql • OpenAPIドキュメントの生成にはutoipa • マクロの表現力を活用してDSLを提供するcrateが多い
17 4. Webアプリ開発に便利なcrateを活用 // type Restaurant { // name: String!
// } // のようなスキーマを定義 pub struct Restaurant(pub query_model::Restaurant); #[async_graphql::Object] impl Restaurant { // リゾルバ async fn name(&self) -> &str { &self.0.name } // ... } async-graphqlによる GraphQLスキーマ定義 #[async_graphql::Object] がcrate提供のマクロ
18 4. Webアプリ開発に便利なcrateを活用 #[utoipa::path( get, path = "/internal/api/{id}/inventories", responses( (status
= OK, description = "成功", body = Vec<Inventory>), (status = NOT_FOUND, description = "存在しない") ), params( ("id" = String, Path, description = "ID", example = "1234") ) )] pub async fn get_inventories(...) utoipaによるOpenAPI ドキュメントのパス定義 #[utopia::path(...)] がcrate提供のマクロ
19 5. 本番で効率よく運用 • 本番ではCloud Runを利用 ◦ 予約が多い年末もコンテナインスタンス2〜4台で 問題なく運用できた •
インフラ全体の運用コストを改善 ◦ 従来のバックエンドのEKSのReplicaSet数減 ◦ Rustバックエンドから効率よくSolrを利用して負荷減 cf. Solr クエリを速度改善したら Solr 全体のパフォーマンスが向上した https://user-first.ikyu.co.jp/entry/2023/12/06/173215
20 最後に | Rustでの開発の感想 • 型に基づく開発体験(rust-analyzerなど)とてもよい • 便利で安定したパッケージ管理やビルド、ツール実行の 仕組みを提供してくれるCargoもとてもよい •
Web開発の細かい情報をもっと増やしたい ◦ 例: 私(kymmt)の細かいアウトプット https://blog.kymmt.com/archive/category/Rust
21 PR | エンジニア採用中です https://www.ikyu.co.jp/recruit/engineer