RubyKaigi 2023 参加レポート

はじめに

2023年5月11日〜13日に長野県松本市で開催されたRubyKaigi 2023に現地参加してきました。自分にとって初めてのカンファレンスだったので、不安と期待が交錯する3日間でしたが、想像以上に楽しく、とても学びになる3日間でした。

Rubyの生みの親であるMatz (まつもとゆきひろ氏) とのツーショット

参加した背景

24卒としてエンジニア就活を行い、就職活動も終盤に差し掛かってきました。しかしChatGPTの登場で幕を開けた第4次AIブームにより、Twitterを開けば大規模言語モデルの開発情報が次々と流れ、テレビをつければChatGPTに関連したニュースを毎日のように耳にするようになりました。就活を始めた2月から現在までの3ヶ月間で、エンジニアリングの世界は驚異的なスピードで進化しており、自分がどんなエンジニアになりたいのか、将来のキャリアプランが曖昧になってきていました。そんな中、偶然にもえりりんさんの投稿を拝見し、ピクシブ株式会社さんが交通費、宿泊費、参加費を負担しRubyKaigi 2023に参加したい学生を募集していることを知りました。ここで、自分より経験のあるエンジニアたちと話す機会を持つことで、自身の目指すエンジニア像や将来のキャリアプランを明確にすることができるのではないかと考えました。ピクシブ株式会社さんの応募は書類選考と面接1回でした。聞いた話によると、10人以上は応募者がいたそうで、その中を通過してきた学生ということもあり、皆、優秀な学生エンジニアでした。自分は法学部法律学科に所属していることもあり、学生エンジニアの友人は片手で数えられるほどしかいないので、ここでの出会いは自分にとって大きな財産になりました。(7月にはサマーインターンで東京に集まるので飲みに行こうと話したり、8月にはハッカソンに出ようという話も上がっています。来年の沖縄で開催されるRubyKaigi 2024でも集まりたいです) RubyKaigi 2023を通して自身のキャリアについて考える機会を得ることができました。このような機会を提供してくださり、ピクシブ株式会社さんありがとうございました!

印象に残ったセッション

Matz Keynote

Matz Keynoteでは、Rubyの30年にわたる歴史やそこから学んだ教訓、そして更に30年生き残るためのビジョンについてのお話がありました。特に印象に残ったのは、Matzが述べた「逆風の中でも耐える、立ち向かう」という言葉です。就活を進める中で、隣の芝が青く見えたり、選択に迷ったりすることがしばしばあります。しかし、Matzのお話からは、自分が選んだ道を信じることの大切さが伝わってきました。辛い時や困難な状況に直面しても、自分自身を信じ続け、選んだ道に固執することで、未来に向かって進んでいけるのだというメッセージを感じました。

Develop chrome extension with ruby.wasm

Develop chrome extension with ruby.wasmでは、Rubychrome拡張を実装するためのフレームワークであるUnloosenの紹介とデモが行われました。特に印象に残ったのは、登壇者が学生だったことです。自分もいつかRubyKaigiで登壇したいと思っていましたが、2回目の参加+学生で登壇されているのを見て、登壇というものが思ったより近くにあるように感じました。また、Unloosenのexamplesが公開されていたので、実際に手元で試してみました。WebAssemblyでRubyを動かすまでのハードルを感じることなく、すぐに拡張機能を作ることができました。

Ruby Committers and The World

Ruby Committers and The Worldでは、YJIT、RBS、Parserなどの各トピックに対するコミッター同士のパネルディスカッションでした。普段からRubyを触っている身として、Rubyのコミッター同士のトークを聞くだけでモチベーションが上がりました。来年はもっと理解できるように英語+低レイヤーの知識を補強しようと思います。

おわりに

今回のRubyKaigi 2023を通して、2つの重要な学びを得ることができました。1つ目は、強いエンジニアになるためには、英語と低レイヤーの知識が必須であるということです。急速に進化するエンジニアリングの世界では、英語で迅速に情報を理解し、高度で抽象的な事象を詳細に分解できる低レイヤーの知識が必要不可欠です。RubyKaigi 2023を通して、この重要性を再認識することができました。残りの学生生活は、英語と低レイヤーの知識の強化に注力して取り組みたいと思います。2つ目は、他の技術者と差別化を図るため+プロフェッショナルとして生き残るために、特定の技術領域において他の誰よりも深い知識を持つという武器を身につける必要があることです。現時点でバックエンド領域に興味があるので、バックエンド領域の技術を深く掘り下げていきたいと思います。改めてピクシブ株式会社さんや関わって下さった皆さんありがとうございました。来年のRubyKaigi 2024も参加しようと考えているので、皆さんとお会いできることを楽しみにしています!

なりたいエンジニア像

3年後になりたいエンジニア像:バックエンドエンジニア

バックエンド領域の専門性を高め、バックエンド領域において他の誰よりも深い知識を持つプロフェッショナルになりたい。

実現のために1年目〜3年目は下記に取り組みます。

  • バックエンド領域の専門性を高める
    • 大規模サービスに携わり、パフォーマンス(ボトルネックの特定、キャッシュの利用など)、データベース(設計、インデックス、負荷分散、データの整合性など)、セキュリティなどのバックエンド領域における専門性を高める。
    • バックエンド言語、およびフレームワークに精通し、カンファレンスやイベントで登壇し、知識を体系的に整理し、他のエンジニアからフィードバックを得る
  • 英語力の向上
    • 定性的な目標 : 英語の技術書、動画、記事、ドキュメントを翻訳無しで理解できる。

5年後になりたいエンジニア像:テックリード

バックエンド領域以外の知見を広げ、ドメイン・システムの全体像を理解し、チームを技術面でリードし、マネジメントできるエンジニアになりたい。

実現のために4年目〜5年目は下記に取り組みます。

  • バックエンド領域以外の知見を広げる
    • バックエンド領域に軸足を置きつつ、サービス開発における幅広い経験を積む。
  • マネジメント力の向上 
    • チームメンバーや他のステークホルダーと積極的なコミュニケーションを心がけ、コミュニケーション力を上げる。
    • 他エンジニアのリソースや進捗にも目を配り、プロジェクト全体の管理能力を磨く。
    • 質の高いコードレビューを通して、システム全体の品質を上げる。

10年後になりたいエンジニア像:CTO

エンジニアリングの専門知識と経験を活かしつつ、ビジネス面と技術面の両面で事業の成長に貢献し続けられるエンジニアになりたい。

実現のために6年目〜10年目は下記に取り組みます。

  • 事業立ち上げ
    • ユーザーに真摯に向き合い、人々が欲しがるプロダクトを作る。
    • 適切な意思決定(技術選定、設計など)を行うために、常に最新の技術を追いかけ、継続的に学習に取り組む。
    • 市場の動向やユーザーのニーズをより深く理解し、技術的戦略の提案を行う。

なぜ1つの技術領域(バックエンド領域)を極めたいと考えているのか

  • RubyKaigi 2023で他の技術者と差別化を図るため+プロフェッショナルとして生き残るために、特定の技術領域において他の誰よりも深い知識を持つという武器を身につける必要があることを学んだから。
  • バックエンド領域に興味があるから。

なぜバックエンドエンジニアなのか

  • 裏側のロジックを構築することが楽しいと感じるから。
  • システムの基盤を担当することに魅力を感じるから。

なぜテックリードなのか

CTOというキャリアパスを考えているため、チームを技術面でリードしていく経験を積みたいから。

なぜCTOなのか

技術で貢献していきたいのと事業を作ることに興味があるから。

なぜ最初に大規模サービスなのか

前提として、最初は1つの技術領域(バックエンド領域)を極めたいと考えています。

  • 大規模サービスでは、大量のリクエストを処理し、安定した運用が求められるので、単に動作するコードを書くだけでなく、パフォーマンスの最適化や適切なデータ構造やアルゴリズムの選択など、バックエンドに関する深い知識を磨くことができると思うから。
  • 大規模サービスでは、チーム内の分業化が進んでおり、バックエンドエンジニアはバックエンドの領域に特化しているので、バックエンドに関する深い知識を磨くことができるから。

なりたいエンジニア像のその先に何を成し遂げたいのか

なりたいエンジニア像のその先は、人生のビジョンである「何かを残す人生にしたい」を体現する「自分が居なくなった後も多くの人の役に立つようなプロダクト」を作っていきたいと考えています。

なぜ何かを残す人生にしたいと思うようになったのか

大学1年生の時に⽣まれて初めて⾝近な⼈が亡くなり、遺体から遺⾻になるまでの過程を⾒たので「⾃分もいつか死ぬんだ」と強く実感した。そこから「どんなに⼤切な物があろうとも、死んだら何も持っていくことはできない。でも残していくことはできる。この残したものこそ⼈⽣の集⼤成なのではないか?それなら何かを残す人生にしたい」と思うようになった。

なぜ事業を作っていきたいのか

IVS2021 NASU*1にスタッフとして参加させていただいて、事業家たちの熱い想いに触れて自分もいつか事業を作っていきたいと思ったから。

*1:日本最大級のスタートアップ企業経営幹部が集まるカンファレンス&コミュニティ

ユーザー間のコードレビューサービス「Duet Code」をリリースしました

サービスの概要

Duet Codeは、①プライベートで書いたコードをレビューしたり、されたりする機会が無い問題②他の人が書いたコードを読んだり、自分の書いたコードに意見を貰うことで、技術力を上げたいニーズを解決するサービスです。レビューしてほしいプルリクエストを投稿し、レビュアーを募集することができます。ログインすることでレビュイーにもレビュアーにもなることができます。

開発理由

プライベートで書いたコードをレビューしたり、されたりする機会が無い問題を解決したかったからです。現状、プライベートだとコードをレビューする機会が無く、プライベートで書いたコードをレビューしてもらえるサービスはMENTAくらいしか無く、契約制(有料)ということもあり、ハードルが高く、もっと手軽にコードレビューが出来たらいいなと思い開発しました。

使用技術

バックエンド

フロントエンド

API関連のコードOpenAPI Generator TypeScript Axiosで自動生成しています。

インフラ

テスト

CI/CD

Lefthookを使用してコミット前にESLintPrettierRuboCopを実行し、コードの品質を保っています。

環境構築

外部サービス

技術選定

Ruby on Rails

他選択肢 : Laravel, Django

選定理由 : 

Next.js

他選択肢 : React, Angular, Nuxt.js
選定理由 :

  • CtoCサービスなのでSEOを意識する必要があり、Pre-renderingをサポートしているから。(React単体ではPre-renderingをサポートしていない)
  • 実務でReactを使用しているので、Angular, Nuxt.jsに比べて少ない学習コストで習得できると思ったから。

TypeScript

他選択肢 : JavaScript, Flow
選定理由 :

  • 型を付与することでプログラムの可読性が向上したり、エディターの補完機能が効いたり、タイポやバグの早期発見が可能だから。
  • Googleトレンドで定常的にFlowよりTypeScriptが優位だから。

Tailwind CSS

他選択肢 : Bootstrap, Chakra UI, styled-components
選定理由 :

  • デザインに可能な限り合わせたかったから。
  • インラインで疑似クラスやレスポンシブ対応できるから。
  • クラス名を考える必要がないから。

MUI

他選択肢 : Bootstrap, Chakra UI
選定理由 :

Fly.io

他選択肢 : Heroku, Railway, Render.com
選定理由 :

  • 無料枠があるから。
  • 一定時間アクセスが無くてもスリープしないから。(Render.comの無料プランだと15分間アクセスが無いとスリープする)
  • 一定期間後にデータベースが初期化されないから。(Render.comの無料プランだと90日後にデータベースが初期化される)
  • 日本語のドキュメントが充実していて、導入が簡単だから。

Vercel

選定理由 :

  • Next.jsとの相性が良く、導入が簡単だから。

Rspec

他選択肢 : minitest
選定理由 :

  • 実務でRSpecを使用しているので、minitestに比べて早く開発できるから。
  • APIテストの便利メソッドが格納されているcommittee-railsREADMEがRSpecで書かれているから。

Cypress

他選択肢 : Selenium
選定理由 :

  • Cypressをインストールするだけで導入が簡単だから。(SeleniumSelenium以外もインストールが必要で手間がかかる)
  • UIが直感的で分かりやすいから。

GitHub Actions

他選択肢 : CircleCI
選定理由 :

Docker

他選択肢 : VirtualBox
選定理由 :

  • 同じ環境を再現することが容易だから。
  • VirtualBoxはホストOS上で完全な仮想化を行い、ゲストOSを起動するためオーバーヘッドが発生し重たいですが、DockerはホストOSのカーネルを共有するため、ゲストOSを起動する必要が無く軽量だから。 

Firebase Authentication

他選択肢 : Auth0
選定理由 :

使用方法

レビュイー

①「ログイン」or「無料で始める」をクリックして、GitHub認証でログインします。

②ヘッダーの「募集する」をクリックします。

③「タイトル」「プルリクエスト」「使用言語」「プルリクエストの説明」「レビューしてほしい点」を入力して「保存する」をクリックします。(GitHub APIを使用してPublicリポジトリのプルリクエストを取得しています)

④レビュアーが「レビューする」をクリックすると通知が届きます。また、レビュアーが「レビューする」をクリックすると、GitHub APIを使用して自動でリポジトリのコラボレーターに追加され、レビュアーにレビューリクエストが届きます。

⑤レビュアーがプルクエストをApproveして、フィードバックを送信すると通知が届きます。通知をクリックし「お礼する」をクリックして、お礼を送信します。お礼を送信するとレビューは完了になります。

レビュアー

①「ログイン」or「無料で始める」をクリックして、GitHub認証でログインします。

②レビュー募集中からレビューしたい投稿を探します。レビューする場合「レビューする」をクリックします。「レビューする」をクリックすると、GitHub APIを使用して自動でリポジトリのコラボレーターに追加され、レビューリクエストが届きます。プルリクエスト上でレビューを行い、問題が無ければApproveしてください。プルリクエストをApproveしたら「フィードバックする」をクリックして、フィードバックを送信します。

③レビュイーがお礼を送信すると通知が届き、レビューは完了になります。

工夫した点

スキーマ駆動開発を導入しました

スキーマ駆動開発とは、OpenAPIの仕様書を最初に定義し、その仕様書をもとにバックエンドとフロントエンドの開発を同時に進める開発手法です。スキーマ駆動開発を導入したことでフロントエンド側、バックエンド側にメリットがありました。フロントエンド側は、openapi.ymlからAPIクライアントのコード自動生成できるので、余分なコードを書く必要が無くなったり、リクエストとレスポンスに型が付与されているので安全に開発を行えたり、モックサーバーを立てることでバックエンドの実装を待つことなく、フロントエンドの実装を進められたり、ドキュメントを見れば、どんなリクエストを送れば、どんなレスポンスが返ってくるのか分かるので、バックエンドのコードを読みに行く必要がなく楽でした。バックエンド側は、OpenAPIの仕様書を最初に定義しているので、実装すべきことが明確で迷うことなく実装できました。

GitHub APIを導入することでユーザーの手間を減らし、UI/UXを改善しました

レビュー自体はプルリクエスト上で行うことを構想していたのですが、①レビュイーがレビュアーをリポジトリのコラボレーターに追加する②レビュアーが招待を承認する③レビュイーがレビュアーにレビューリクエストを送るという手順が必要でした。これを手動で行うとレビューをするまでに数日かかってしまいます。この手間を省くためにGitHub APIを導入し、レビュアーが「レビューする」をクリックするだけで手順を自動化し、UI/UXを改善しました。

苦労した点

Firebase AuthenticationのidTokenを用いてバックエンドで検証し、UIDをDBに保存するまでのJWT認証の実装に苦労しました

フロントエンドからFirebase Authenticationに認証情報を送る②認証に成功するとidTokenが返却される③フロントエンドからidTokenをバックエンドに送り、idTokenを検証するメソッドが格納されているfirebase-auth-railsを使用して、改竄されていないか検証する④検証に成功するとpayloadが返却されるので、payloadからuidを取得してDBに保存するまでのJWT認証の流れを理解し、ミニアプリを作って試しながら、理解を深めて実装していきました。

なぜFirebase Authenticationを導入したのか

  • 様々な認証プロバイダをサポートしていて、GitHubログインを簡単に実現できるから。
  • OAuth/OpenID Connectなどの認証プロトコルをサポートしていてセキュリティの高い認証フローを実装出来るので、自前で認証を構築し、GitHubのメールアドレス、パスワードをDBに保管するより安全に管理できるから。

なぜidTokenを検証する必要があるのか

idTokenはBase64で暗号化されており、第三者でも簡単に復号できてしまうため、改竄される恐れがあるから。

なぜスキーマ駆動開発を導入したのか

使用したことのない技術を多く使用していて、実装前に技術をキャッチアップしたのですが、バックエンドの実装が完了してからフロントエンドの実装を進める手法だと、余分なキャッチアップコストが掛かってしまうと思ったので、同時並行で両方の実装を進めたかったから。

作り直したい部分

バックエンドのインフラをFly.ioからAWSGCPなどのパブリッククラウドに作り直したいです。理由は2点あります。1点目は、実務ではAWSGCPなどのパブリッククラウドが一般的に使用されているため、AWSGCPなどのパブリッククラウドに作り直すこと自体が勉強になるからです。2点目は、Fly.ioダッシュボードは見づらく、カスタマイズに制限があり、スロークエリの特定やトレースの確認、CPUの使用率、メモリの使用率、リクエスト数、レイテンシなどのアプリケーションのパフォーマンスに関する指標が把握しづらいため、サービスを運用していく上で不便に感じているからです。

自信のあるコード

routescontrollerです。DHHはどのようにRailsのコントローラを書くのかという記事を参考にデフォルトのCRUDアクションであるindex show new edit create update destroyのみを使うようにしました。

フィードバックをどう改善したのか

RubyKaigi 2018のデザインを担当されたmachidaさんにフィードバックをいただき、キャッチコピーを変更したり、デザインを改善しました。他にも面接で「パフォーマンスは推測するのではなく、計測した方がいい」というフィードバックをいただき、APMツールを導入し、パフォーマンスチューニングをしました。

どんな学びを得たのか

  • 個人開発は長期戦になるので、モチベーションを管理するのが一番難しい。最初から完璧を目指すのではなく、まずは終わらせることを意識する。
  • 記事は参考になるが誤植もあるので、一次情報を見る癖を付けた方がいい。
  • 1ヶ月前に書いたコードが何をしたいのか分からないことがあるので、出来る限りコードは綺麗に書く。
  • エラーの大半はログを見れば解決する。
  • 技術はアウトプットすることで理解が深まる。
  • 要件定義、プロトタイピング、リソース設計、DB設計、実装、テスト、リリースをやってみてサービス開発の全体像が分かった。
  • フロントエンド、バックエンド、インフラをやってみてバックエンドの開発をしている時が一番楽しいと感じることに気付いた。