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
一休.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.5k
一休.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.4k
rails new --api してからやったこと 〜2017年・夏〜 / EC Tech MTG 3
kymmt90
0
930
カテゴリ階層の拡張を目的とした階層的トピックモデル / A hierarchical topic model for expanding category hierarchies
kymmt90
0
640
Other Decks in Programming
See All in Programming
yield再入門 #phpcon
o0h
PRO
0
800
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.2k
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
140
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
460
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
160
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
420
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
190
Android CLI
fornewid
0
190
関数型プログラミングのメリットって何だろう?
wanko_it
0
200
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
Featured
See All Featured
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
380
Bash Introduction
62gerente
615
220k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
230
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
660
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
190
Joys of Absence: A Defence of Solitary Play
codingconduct
1
420
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
570
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
460
The Spectacular Lies of Maps
axbom
PRO
1
870
Navigating Weather and Climate Data
rabernat
0
410
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