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
Railsで海外9ヵ国にサービス展開している話 / Rails i18n
Search
rince
February 26, 2021
Programming
3
1.7k
Railsで海外9ヵ国にサービス展開している話 / Rails i18n
2021/2/26 @銀座Rails#30
Railsでのi18nの進め方と少人数で海外展開する上での設計・実装・テスト・デプロイの工夫についてお話ししました。
rince
February 26, 2021
Tweet
Share
More Decks by rince
See All by rince
あらゆる商品を扱う商品データベースを再設計した話 / product db re-architecture
rince
11
5.9k
Elasticsearch入門 〜前編〜
rince
0
250
ActiveSupport::Concern で学ぶRuby
rince
1
300
Railsを6年間やってきたぼくが最近Railsでハマったこと
rince
3
550
プロジェクトをまたいだIssue管理
rince
0
2.2k
そうだ Rack 作ろう。
rince
2
90
Lean Startup
rince
0
170
Yahoo!主催のOpenHackDayJapanに参加してJAXA賞をいただきました
rince
1
130
Other Decks in Programming
See All in Programming
距離関数を極める! / SESSIONS 2024
gam0022
0
290
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
230
Kaigi on Rails 2024 〜運営の裏側〜
krpk1900
1
230
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
480
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
Webの技術スタックで マルチプラットフォームアプリ開発を可能にするElixirDesktopの紹介
thehaigo
2
1k
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
340
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
Featured
See All Featured
Bash Introduction
62gerente
608
210k
Designing for humans not robots
tammielis
250
25k
How GitHub (no longer) Works
holman
310
140k
Designing for Performance
lara
604
68k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Why Our Code Smells
bkeepers
PRO
334
57k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Designing the Hi-DPI Web
ddemaree
280
34k
A Tale of Four Properties
chriscoyier
156
23k
Teambox: Starting and Learning
jrom
133
8.8k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
28
2k
Transcript
Railsで海外9ヵ国に サービス展開している話 2021/2/26 @銀座Rails rince (@kazumax1218)
rince (@kazumax1218) • 2011- カカクコム(食べログ→キナリノ) • 2018- メルカリ(ソウゾウ→メルペイ) • 2020-
mybest 旅とキャンプとサウナが好き。 自己紹介 0. はじめに
• Railsのi18nの基本をお伝えして、海外展開の開発面でのハードル がそこまで高くないことを知っていただく • 少人数での海外展開の工夫をお伝えして、少人数でも海外展開でき るということを知っていただく • 日本から海外にチャレンジするプロダクトが増えたらいいな😊 本発表のゴール 0.
はじめに
本日のアジェンダ 1. Railsのi18nの基本 2. どんなサービスを海外展開してるのか 3. 少人数で開発/運用するための工夫 ◦ 設計・実装 ◦
テスト・デプロイ 4. まとめ 0. はじめに
1. Railsのi18nの基本
i18n = internationalization • 国際化・多言語化 • 先頭のiと末尾のnとの間に18文字あるのでこのように略される i18nとは? 1. Railsのi18nの基本
国際化 • 使われるすべての文言やロケール固有の要素 (日付や通貨フォー マットなど) の抽象化 ローカライズ • 具体的な翻訳方法を提供したり、そのためのフォーマットを提供し たりすること
国際化とローカライズ 1. Railsのi18nの基本
1. ロケールの設定 2. コード中の文言を抽象化する 3. 訳文を与えて翻訳する 4. 日時や金額をローカライズする i18nの進め方 1.
Railsのi18nの基本
• デフォルトのロケールを変更する場合 config/application.rb • パラメータやドメインに応じてロケールを変更する場合 application_controller.rb 1. ロケールの設定 config.i18n.default_locale =
:en around_action :switch_locale def switch_locale(&action) locale = extract_locale || I18n.default_locale # paramsやドメインからlocaleを抜き出す I18n.with_locale(locale, &action) end ※ I18n.locale= を使うと同じスレッドで処理される以後のリクエストも影響を受けてしまう 1. Railsのi18nの基本
I18n.t (translate) メソッドでコード中の文言を置き換える • 各訳文の意味を適切に表すキーを与える 2. コード中の文言を抽象化する <p>Hello!</p> <p>Hello, itadori!</p>
<p><%= t :hello %></p> <p><%= t :greeting, name: 'itadori' %></p> 1. Railsのi18nの基本 動的な値は引数で渡す
各国の辞書ファイルに訳文を追加する 3. 訳文を与えて翻訳する 1. Railsのi18nの基本 # config/locales/en.yml en: hello: 'Hello!'
greeting: 'Hello, %{name}!' # config/locales/pt-BR.yml pt-BR: hello: 'Olá!' greeting: 'Olá, %{name}!' %{} で変数を式展開できる
I18n.l (localize) メソッドやヘルパーメソッドで日時や金額を現地の フォーマットに変換する 4. 日時や金額をローカライズする 1. Railsのi18nの基本 ※ https://github.com/svenfuchs/rails-i18n
にほとんどの言語の翻訳ファイルがある <h3><%= locale %></h3> <p><%= l Date.today %></p> <p><%= number_to_currency 1000 %></p>
簡単😊
Viewに大量の文章が含まれている場合は言語別にテンプレートを分ける ことも可能 • ex) プライバシーポリシー, 利用規約など • ビューファイルの拡張子の前にロケールを付ける 補足1: ローカライズ済みビューテンプレート
1. Railsのi18nの基本 app/views/pages ├── privacy_policy.en.html.slim ├── privacy_policy.pt-BR.html.slim ├── ... └── privacy_policy.vi.html.slim
Viewファイルのパスに沿った階層で訳文を定義すると、対応するView 内で「. +キー名」で訳文を参照できる • 同じキー名がいろんなページで使われる場合に便利 補足2: 訳文の遅延探索 1. Railsのi18nの基本 en:
users: index: title: 'Title A' show: title: 'Title B' app/views/users/index.html.erb <%= t '.title' %> <%# => "Title A" %> <%= t '.title' %> <%# => "Title B" %> app/views/users/show.html.erb config/locales/en.yml
2. どんなサービスを海外展開してるのか
徹底した自社検証と専門家の声をもとに 本当に良いモノを紹介して、 あなたの”選ぶ”をお手伝いする おすすめ情報サービス サービス内容 https://my-best.com 3,300万人 月間訪問者数(MAU)
商品を自社で実際に購入し、 比較・検証してデータベース化 各々に最適な商品をランキングで紹介 ①比較コンテンツ 専門家やインフルエンサーが 自身の愛用品の中からおすすめ ②アイテムリスト
世界11ヵ国にサービス展開 アメリカ ブラジル イギリス 中国 日本 タイ ベトナム インドネシア 台湾
展開国数 11 ヵ国 インド フィリピン 2. どんなサービスを海外展開してるのか ブラジル・インドネシア・タイ・台湾では既に月間数百万PVのアクセス
各国に合わせたコンテンツを作成 2. どんなサービスを海外展開してるのか Brazil (https://mybest-brazil.com.br) Thailand (https://my-best.in.th) 各国の編集者・ライターがいて、各国に合わせたコンテンツを作成している
3. 少人数で開発/運用するための工夫
• フルタイムのエンジニアが4人しかおらず、国内でのPMFが最優先の ため、海外に割けるリソースは1名以下 (We are hiring!) • 国内版は機能開発が頻繁に行われるため、国内版とはコードを分ける • 中国は各種SaaSが使えないため、中国以外の海外9ヵ国に対応する
(中国はWordPressで運用) • 機能は国によらず同じだが、コンテンツは各国で異なる • 今後まだまだ展開国は増える可能性がある 前提 3. 少人数で開発/運用するための工夫
• できるだけ開発/運用コストを抑える ◦ 1名のリソースで開発/運用が回るか? • 今後展開国が増えても破綻しない仕組みにする ◦ 20ヵ国になっても開発/運用が回るか? 基本方針 3.
少人数で開発/運用するための工夫
3-1 設計・実装 👈 3-2 テスト・デプロイ
• 開発メンバーが少なく、できるだけ運用コストを減らすため • 現状では国ごとの機能のローカライズはそこまで必要ないため 1リポジトリ複数DBで運用 選択肢 説明 向くケース 複数リポジトリ 複数DB
国ごとにコードもDBも分ける ・開発リソースがある / 展開国が少ない ・各国で機能のローカライズが必要 1リポジトリ 複数DB 各国コードは共通で、国ごとに DBを分ける ・開発リソースがない / 展開国が多い ・各国で機能のローカライズが少ない 1リポジトリ 1DB 各国コードもDBも共通で、カラ ムやテーブルでデータを分ける ・データは同じで言語が異なる ・翻訳サイト 3. 少人数で開発/運用するための工夫(設計・実装)
• 開発メンバーが少なく、できるだけ運用コストを減らすため • 現状では国ごとの機能のローカライズはそこまで必要ないため 1リポジトリ複数DBで運用 選択肢 説明 向くケース 複数リポジトリ 複数DB
国ごとにコードもDBも分ける ・開発リソースがある / 展開国が少ない ・各国で機能のローカライズが必要 1リポジトリ 複数DB 各国コードは共通で、国ごとに DBを分ける ・開発リソースがない / 展開国が多い ・各国で機能のローカライズが少ない 1リポジトリ 1DB 各国コードもDBも共通で、カラ ムやテーブルでデータを分ける ・データは同じで言語が異なる ・翻訳サイト 3. 少人数で開発/運用するための工夫(設計・実装) どの国かを環境変数で持ち、database.ymlのdatabaseやhostの値を切り替える 👈
保守性・可読性を高めるためになるべく国ごとの分岐を入れない • ex) タイムゾーン, 機能のON/OFF, GAのトラッキングIDなどの各種設定 コード内に国ごとの分岐を入れない 3. 少人数で開発/運用するための工夫(設計・実装) config.time_zone
= case ENV['OVS_CODE'] when 'br' 'Brasilia' when 'id' 'Jakarta' ... when 'vn' 'Hanoi' end
https://github.com/rubyconfig/config を使って定数を出し分ける コード内に国ごとの分岐を入れない 3. 少人数で開発/運用するための工夫(設計・実装) # config/settings/br/settings.yml time_zone: 'Brasilia' #
config/settings/id/settings.yml time_zone: 'Jakarta' # config/application.rb Settings.add_source!("#{Rails.root}/config/settings/#{ENV['OVS_CODE']}/settings.yml") Settings.add_source!("#{Rails.root}/config/settings/#{ENV['OVS_CODE']}/#{Rails.env}.yml") Settings.reload! config.time_zone = Settings.time_zone
管理画面のアカウント管理のコストを削減するためにAWSのCognitoを用い てアカウントを一元管理し、グループでアクセス権限を分ける Cognitoでアカウントを一元管理 3. 少人数で開発/運用するための工夫(設計・実装)
3-1 設計・実装 3-2 テスト・デプロイ 👈
GitHub Actionsのstrategy.matrixを用いて各国でRSpecを並列実行 各国並列でテストを行う jobs: rspec: ... strategy: fail-fast: false matrix:
ovs_code: ['br', 'id', 'in', 'ph', 'th', 'tw', 'uk', 'us', 'vn'] env: ... OVS_CODE: ${{ matrix.ovs_code }} 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
運用コストを最小限にするためのインフラ 3. 少人数で開発/運用するための工夫(テスト・デプロイ) ・・・ Indonesia (ap-southeast-1) Brazil (sa-east-1) AWSのFargateを用いて、トラフィックや展開国が増えてもスケールする 仕組みを構築
Slackから全世界に一括デプロイできるようにして、デプロイの手間を削減 ChatOpsで全世界に一括デプロイ 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
国とPR番号を指定して、レビュー環境にデプロイ • 本番相当のデータで各国の動作確認が可能 • 各国の開発用データの準備の手間を削減 リリース前の各国での動作確認 3. 少人数で開発/運用するための工夫(テスト・デプロイ)
大きな問題もなく、 海外9ヵ国に展開できています😊 (小さな問題はいろいろとあったので、その話もまたどこかでw)
4. まとめ
• Railsのi18nのサポートのおかげで、開発面においては海外展開の ハードルはそこまで高くない • 少人数のリソースでも開発/運用を工夫することで、複数ヵ国に海外 展開可能 • 日本から海外にチャレンジするプロダクトを増やしていきましょう 💪 まとめ
4. まとめ
ご清聴ありがとうございました!