はじめに
こちらは バイセルテクノロジーズ Advent Calendar 2024 の15日目の記事です。 昨日は中舘さんによる要件定義からリリースまでやり遂げたことでプロダクトエンジニアとして成長できた話でした。
こんにちは。株式会社BuySell Technologies(以下、バイセル)でバックエンドエンジニアをしている金澤(@urban-side)です。
社内では現在基幹システムのリプレースが進んでおり、機能や業務スコープごとに切り出していく中で様々なプロダクトが立ち上がり、順次開発が進められています。
バイセルでは元々Next.js + GraphQLが主流でしたが、技術選定を各プロダクトチームが行う中でVanilla React/Go+RESTを選択するチームも増えてきました。Reactだけで完結するのか、Next.jsまで手を出すのか。Go + RESTと言ってもフレームワークは使うのか、アーキテクチャはどうするのか。これはチームによって様々です。
それに伴い、このタイミングで入社・配属が迫る新卒や内定者インターン生向けのカリキュラムも改めて刷新する必要が出てきた、というわけです。
本記事では、Webアプリの基礎を身につけるカリキュラムを作成する際に気を遣ったことについて書いていきます。これはある種の宗教・派閥めいた話題でもあるでしょうか。 「この著者はあちらを取ったが、自分ならこちらを取る」と議論していただいたり、別の観点がありましたらそれをご教示いただいたりと、考えるきっかけになれば嬉しいです。
カリキュラムの刷新
今まで、バイセルにおける新規プロダクト開発ではNext.js + Go + GraphQLという構成が主流でした。一方で、ここ1年ほどで一気に加速した基幹システムのリプレースプロジェクトで立ち上がったプロダクト群では、少し変わってきています。
フロントエンドにNext.jsを使っているとしても静的サイトとして配信することが増えてきたり、プロダクトによってはVanilla Reactを採用するケースも増えてきました。バックエンドではGo + REST API構成かつOpenAPIによるスキーマ駆動開発が主流です。各チームが自由にフレームワーク選定やアーキテクチャを設計しますが、規模感や要件を整理した結果、このような構成を取ることが多くなっています。
ちなみに、バイセルにおける技術選定のあれこれについてはこちらの記事で書かれていますので、ぜひご一読ください。
バイセルで現役の保守すべき旧システムはRuby on Railsで書かれていますが、今後入社する新卒エンジニアやそれに向けた内定者インターンの方々は原則新規プロダクトに配属されることを考えると、身につけてほしい技術スタックも変わってきます。
ここに、React + Go + REST API版のカリキュラムを整理しなければ、というモチベーションが生まれました。
カリキュラムの目的
バイセルで行っているカリキュラムの大目標は「配属先で業務をするために必要最低限の技術や仕事の進め方を学ぶこと」です。この目標をアプリケーションの開発を通じて体験していきます。
カリキュラム修了時点で想定している習得項目は以下のとおりです。
- バイセルで必要な基本的なWebアプリケーション開発の実装ができる
- GitHubを使用してブランチ戦略やPR作成、マージなど開発の一連の流れを習得する
- 報告・連絡・相談が適切なタイミングでできるようになる
- 配属先で業務をするために必要十分な信頼関係をメンター・サポーターと構築できる
- 基本的なタスク管理(タスク分解・見積もり)ができる
今回の本題は、バイセルで必要な基本的なWebアプリケーション開発の実装ができるようになるため、必要な要素をどのようにカリキュラムに組み込んだかとなります。
カリキュラムの要件
前段の内容を踏まえ、改めてカリキュラムに必要な要件を優先度が高い順に3つ定めました。
- React(Next.js) + Go + REST APIの構成かつスキーマ駆動開発であること
- ライブラリ、フレームワークはできる限りどのプロダクトでも利用されている(もしくは近しい)ものにすること
- カリキュラムアプリ自体のメンテナンスが容易であること
技術スタックを満たすことを最優先とし、チームごとにライブラリやフレームワークが分かれていることを考慮して、初期状態で導入するものをできるだけ少なくしつつ、最大公約数的なものを選定しました。独自に選定したフレームワークが導入できるような余裕を持たせています。最後に、各種バージョンアップやカリキュラム実施後のフィードバックを迅速に反映させられるようなメンテナンス性を維持したいと考えました。
作っていこうカリキュラム
上記に定めた要件を軸に、技術選定を含めた簡単なWebアプリを実装しました。進めていくうちに「これは思想だ」「〇〇派ですか??」「一番クセがないものを探せ」などの舌戦が多数見受けられ、モノづくりにフラットな視点を持つことは難しいと改めて考えさせられました...。
せっかくなので、その中で生まれた意見交換について簡単にご紹介していきます。
monorepoの採用
本カリキュラムでは、フロントエンドとバックエンドを1つのリポジトリで管理するmonorepoを採用しています。
フロントエンド・バックエンドともにOpenAPIからコードを生成する都合上、相対パスによる指定がもっとも楽だと考えました。curriculum-front, curriculum-server, curriculum-doc, ...のようなリポジトリを切ってGit Submoduleとして管理することも考えましたが、各領域で担当者のいるチーム開発ではなく個人開発であることから、リポジトリ管理を複雑化する優位性がないと判断しています。来年度以降も保守・改良することを考えると、むしろリポジトリは分けないほうが良いでしょう。
また、サンプルリポジトリをclone後、自身専用のものとしてorganization内にpushする都合上、研修用リポジトリが散逸するのを防ぐ副次的効果もありました。
Prettier採用の見送り
開発初期の議論にて、コードのformatterとして広く使われているPrettierの採用を見送ることになりました。
組み合わせて使用されるESLint自体にもformatterとしての機能があること、ESLintからPrettierへのフォーマットルール変換ライブラリを使う可能性が高く、できる限り採用するライブラリを抑えるという目的に沿えないこと。何より「ESLint + Prettierは絶対セットである」という固定観念を持って欲しくないこと(その選択を自分でする機会を奪いかねない)が決め手となり、不採用となりました。
GoのWebアプリ向けフレームワークの選定
今回のカリキュラムではGoのWebアプリケーション向けフレームワークにogenを採用しています。
誤解を恐れずにいえば、Goでサーバーを作るとなった際、選択肢に上がるフレームワークといえばechoとginでしょう。直近ではhumaが話題になったでしょうか。
本カリキュラムはスキーマ駆動開発を最優先としているため、OpenAPIからコード生成を行えることを優先した結果、ogenを選択しました。特に、OptionalやNullableにも型がきっちり定義されていること、レスポンスの型までOpenAPIに準拠してかっちりコード生成されることが決め手になりました。
コード生成可能な類似ライブラリとしてはoapi-codegenが存在しますが、デフォルトのルーティングエンジンにechoやginなどの別フレームワークを利用するため、そちらに依存してしまうのではないかと考えて採用を見送っています。採用フレームワークが増える分だけ、メンテナンスコストが増加することも懸念点として上がっています。
実際に運用して良かった点・後悔した点
ここで、実際のインターン生やそのメンター陣からの振り返りをいくつか抜粋してご紹介します。記事公開時点ではカリキュラムの途中であるため全て終わった後の感想とは異なるものですが、参考にしていただけると幸いです。
フロントエンド構成はちょうど良い
ReactとMUIが主軸で、あとはスッキリしている印象を受けます。足りないのは日付ライブラリくらいですが、ライブラリ選定の第一歩を踏めるためある意味良かったです(メンター・フロントエンドエンジニア)
oapi-codegenを採用した方が良かったのでは?
ogenを採用したタイミングでは、「チームによってechoやginなど採用フレームワークがバラバラだから、影響範囲がOpenAPIからのコード生成で収まる他のフレームワークを」と思っていたのですが、oapi-codegen + チームごと利用しているフレームワークという構成の方がより実務に入りやすいのではとも思います(メンター・バックエンドエンジニア)
バックエンドをHandler層のみ実装したのは良かったのか?
今回作成したモックアプリではHandler層のみを実装しており、その中でResponseした内容がClientへ返るようになっています。ここからレイヤードアーキテクチャを作ろうとした場合、バックエンド未経験者がいきなり作れと言われてもハードルが高いです。
一方で、最初からレイヤードアーキテクチャで実装されていても混乱するという意見も上がりました(メンター・フロントエンドエンジニア)
フレームワークがやっていた部分を自分で触る機会ができて良い
O/Rマッパやマイグレーションが内包されているフレームワークの使用経験はありましたが、これらを自ら選定して導入、使用する経験ができたことは初めてだったので良かったです。自分で選定するからこそ、何故その技術を使う必要があるのかという部分まで考えることができたので、より深い理解に繋がりました。
一方で、自由度の高さはそれだけレビュー観点の増加につながるはずなので、メンターの方には負担になってる? と思うことがあります(インターン生)
一方で、選択肢の広さによって迷うことも
自由度の高さはその通りで、好きな構成で実装できることは魅力でした。一方で、初学者としては教科書的な道筋を立ててほしい気持ちが一部あったのも事実です。実装例を各フレームワークごと用意していただけたら、手を動かす助けになったと感じていますが、求めすぎかもしれないですね(インターン生)
結びに
最後まで読んでいただき、ありがとうございます。
本記事では、新たにバイセルに入ってくれる仲間が少しでも不安なく業務に入れるよう、オンボーディングに使う教材としてのモックアプリにどのような考えで技術や設計を採用したかを書かせていただきました。
実際に25年度新卒のインターン生に利用してもらう中で、意図して採用した技術を意図通り使ってくれていること、あえてその形にしたものが意図しなかったところで活用されていることなど、たくさんのフィードバックを頂きました。メンター陣としても気付くことが多く、少しでも良いものにしていかねばと改めて感じています。
12月も半ば。冬から春に向かい仲間が増える時期ではないでしょうか。エンジニアキャリアをスタートさせる方やそのメンターに、この記事が何かの形でお役に立ったならこれ以上の喜びはありません。
バイセルでは一緒に働くエンジニアを募集しています、興味がある方は、以下よりご応募ください。 herp.careers
明日の バイセルテクノロジーズ Advent Calendar 2024 は 大石さんによる 「25卒インターン生のペーペーが積極的にレビューに参加したら成長を感じられた話」です。 お楽しみに!