Slide 1

Slide 1 text

Railsで大規模Webアプリケーションを 開発するときに知っておきたいテクニック Qiita 株式会社 山田 航

Slide 2

Slide 2 text

● 山田 航(やまだ わたる) ● Webアプリケーションエンジニア ● 2021年に Qiita に新卒入社し、Qiita の開発をしています! ○ Rails 暦はまだ2年半... ■ Rails について詳しいわけではない ■ Qiita の Rails の話をします! 自己紹介 人間のすがた ウミウシのすがた

Slide 3

Slide 3 text

アジェンダ ● Qiita の Rails について紹介 ● 大規模 Rails 開発でつらいポイント1 ○ Qiita でどのように解決しているか ● 大規模 Rails 開発でつらいポイント2 ○ Qiita でどのように解決しているか

Slide 4

Slide 4 text

Qiita の Rails について紹介 Qiita は Rails を使っています!! ● 現在 12 歳: 2011 (Rails 3.0.3) ~ 2023 (Rails 6.1.7) 1つのRails 内に「Qiita」「Qiita Team」「Qiita Jobs」全部入っています! ● コードは一緒だけど、インフラレベルだと分かれている rails stats コマンドで計測したところ、なんと15万行! ● テストのディレクトリが入っていないので、実際にはその 2倍くらい

Slide 5

Slide 5 text

大規模 Rails 開発でつらいポイント そもそも Rails の魅力って... ● 少ない記述 で 素早く Webアプリケーションを作れる ➡ 数々のスタートアップ企業で採用された 成功したスタートアップ企業はどうなった? ● Rails を使い続けた。しかし、サービスは複雑になっていった ➡「MVCだけでは収まらないもの」が出現した (後で具体例を出します) ○ Model か Controller か、どちらに実装すればいいか悩む ... ○ 無理にMVCに収めようとすると、Fat Model や Fat Controller になる... 「MVCだけでは収まらないもの」を Qiita で具体的にどのように解決しているか紹介!

Slide 6

Slide 6 text

「MVCだけでは収まらないもの」を Qiita で具体的にどのように解決しているか 2つの具体例で紹介 1. 複雑な条件のコレクションの作成 ○ 例: Qiita のタイムラインページに表示する記事 2. フロントエンドに渡す様々なデータの取得 ○ 例: Qiita のトップページに必要なデータの取得

Slide 7

Slide 7 text

「MVCで収まらないもの」: ① 複雑な条件のコレクションの作成 例: Qiita のタイムラインページに表示する記事 ● 条件 ○ 時系列順に、最新N件を表示 ○ フォローしているユーザーの記事を表示 ○ フォローしている Organization の記事を表示 ○ フォローしているタグの記事を表示 ○ ミュートしたユーザー・タグの記事は非表示 ○ フォローしているユーザーの記事だけ 出せるパターンも用意したい ● Rails でどう実装する? ○ Model や Controller に実装すると単一責任の原則に反する ... ○ どちらかに実装しても同様のパターンが増えるたびにクラスが肥大化する ...

Slide 8

Slide 8 text

「MVCで収まらないもの」: ① 複雑な条件のコレクションの作成 解決方法: 「Iterator パターン」を使う 1. TimelineBuilder クラスを作成 ○ Enumerable を include する ○ 記事を取得する処理を記述する 2. Controller で TimelineBuilder.new(user) を呼ぶ 「このパターンはこう実装する」が決まっている = 実装場所に迷わない & 肥大化しない Qiita 内ではこのパターンを利用した XXXBuilder が 25ファイル存在する

Slide 9

Slide 9 text

「MVCで収まらないもの」: ② フロントエンドに渡す様々なデータ 例: トップページに必要なデータ ● おすすめ記事 ● フォローしているタグ ● 開催中のイベント ● 記事投稿キャンペーン ● ユーザーランキング Rails でどう実装する? ● すべて Controller に書こうとすると、とんでもない量になる ● サイドバーなど、別のページでも同じデータを利用する場合、共通化したい

Slide 10

Slide 10 text

「MVCで収まらないもの」: ②フロントエンドに渡すデータの取得 解決方法: GraphQL を活用する 1. GraphQL の resolver を定義 ○ Qiita では graphql-ruby gem を使用 2. Controller にクエリを記載 ○ 何が必要かを記載するだけ 3. action で GraphQL を実行してデータを取得 「このパターンはこう実装する」が決まっている = 実装場所に迷わない & 肥大化しない データの取得は基本 GraphQL Query で行い、 作成・更新・削除は GraphQL Mutation で解決

Slide 11

Slide 11 text

ここまでのまとめ サービスが複雑になり、「Rails の MVC では収まらないもの」が出現した ● Model か Controller か、どちらに実装すればいいか悩む ... ● 無理にMVCに収めようとすると、Fat Model や Fat Controller になる... Qiita は「MVCで収まらないもの」をパターン化して解決方法を定めた ● 複雑な条件のコレクションの作成 ➡ Iterator パターンで解決 ● フロントエンドに渡すデータの取得 ➡ GraphQL で解決 「このパターンはこう実装する」が決まっている = 実装場所に迷わない & 肥大化しない

Slide 12

Slide 12 text

「Rails の MVC では収まらないもの」の補足 今回紹介した方法以外にも「MVCで収まらないもの」の解決方法ある ● DDD・クリーンアーキテクチャなど、設計手法 ● Serviceオブジェクト・Formオブジェクトなどのパターン ● などなど 自分達の Rails でよく起こる問題と、それに合う解決方法を見つけることが大事

Slide 13

Slide 13 text

大規模 Rails 開発はここもつらい コード品質の担保

Slide 14

Slide 14 text

大規模 Rails 開発でつらいポイント2: コード品質の担保 リファクタリングなどの保守作業は売上に直結しないので、工数を確保しづらい... ● 負債が積み上がり、リプレイスするしかない状態になってしまう Qiitaはどうやってコード品質を担保している? ● ドキュメント文化 ○ yard などのコメント、仕様をまとめたドキュメント、コーディング規約 ● ツールや自動テストを駆使 ○ Rubocop, yard, CI でのテストの定期実行など ■ RSpec のカバレッジは 90% 超え!

Slide 15

Slide 15 text

大規模 Rails 開発でつらいポイント2: コード品質の担保 でも、できていない部分もある... ● 主要ライブラリのアップデートがギリギリ ○ まだ Rails 6 から Rails 7 に更新できていない... ○ Dependabot がどんどんふえていく... ● 残り続けている負債 ○ 使わなくなったカラムを放置している ○ 黙認しているバグ ➡ 1つずつ地道に改善していくしかない!改善に向けて、開発チームで推進中! ● コード品質・開発環境の改善を推進するメンバーを一人決めておく ● チームのタスクに必ずコード品質・開発環境の改善を一定割合入れる

Slide 16

Slide 16 text

まとめ サービスが複雑になり、「Rails の MVC では収まらないもの」が出現 ● 「このパターンはこう実装する」が決まっている = 実装場所に迷わない & 肥大化しない コード品質の担保
 ● 文化やツールで、そこそこ担保できている ● まだ足りないので、地道に改善を進めていく 紹介したテクニックなど、後日 Qiita に記事としてまとめる予定です!

Slide 17

Slide 17 text


 
 意見・要望あたら Dis
 
 
 
 
 
 
 
 
 
 
 Qiitaに対するご意見・ご要望がありましたら Qiita Discussions にどうぞ! さいごに もうすぐ12月! 「Qiita Advent Calendar 2023」 あなたの Rails について 記事を書いてみませんか? 本日公開! 「 AIサジェスト機能」 クローズドベータ募集中です ぜひご応募ください! 今週金曜開催! 「Wantedly x Qiita Meetup」 Qiita のフロントエンドの話を します(先輩エンジニアが)