NestJS を使ってジョブメドレーアカデミーのバックエンド開発をどのように行なっているのか
はじめに
みなさん、こんにちは。エンジニアの山田です。今回はジョブメドレーアカデミー(以下、アカデミー)の開発の皆さんに集まってもらい、TypeScript と NestJS を使ったバックエンド開発をどのように行なっているのかをインタビューしました。
以前、アカデミーがリニューアルした際にチームメンバーにインタビューした note もあるので、未読の方はぜひそちらもご覧いただければと思います。
インタビュイー紹介
岸田さん
SES 会社で業務システム開発、バングラデシュに支社があるオフショア開発をしている会社でブリッジエンジニアという経験を経て、2019 年メドレー入社。 その後ジョブメドレーで開発をリード。現在はアカデミーのプロダクト責任者を務める。
熊本さん
2019 年メドレーに新卒入社。半年の研修を経てジョブメドレーの開発に携わる。現在はアカデミーの開発に携わる。大学では機械学習を用いた自動車の自動運転の研究をしていた。
牧野さん
2021 年 11 月にメドレー入社。不動産業界の SaaS を開発している会社でのマネージャー・エンジニアを経験。現在はアカデミーの開発に携わる。
徳永さん
2022 年メドレーに新卒入社。 OJT 期間中からアカデミーの開発に携わる。大学では、対話 AI システム・ AI との対話用プラットフォームの研究開発をしていた。
アカデミーのアーキテクチャ
山田: 早速ですが、現在のアカデミーのアーキテクチャについて話を伺いたいと思います。全体の構成としては現在どんな形になっているんでしょうか。
岸田: 以前話をしたところから大幅に変わったところはないですが、大まかにはこんな感じになっています。
山田: ありがとうございます、分かりやすいですね。
山田: Web フロントエンドに関しては Next.js とグローバルの状態管理として Apollo Client を使っていると伺っています。バックエンドは色々あると思うのですが、DB に関しては PostgreSQL を使っているんですよね?
岸田: はい、ORM としては Prisma を使っています。
山田: こうした開発環境はどのように決まったんでしょうか?特に、開発言語を全て TypeScript で統一する、という意思決定が先にあってバックエンド側のフレームワークは NestJS にしようとなったのか、逆に NestJS を使おうとして TypeScript になったのかをお聞きできれば。
岸田: 細かいところまでは記憶にないのですが、TypeScript を使って型で開発をしたいというのが一番大きい理由でした。
山田: まずは TypeScript からだったんですね。そこから Web フレームワークとしては Express など他の物もあったと思いますが、NestJS を採用した理由は何だったのでしょうか?
岸田: そうですね、色々選択肢はあったと思うんですが、現実的にサービスを運用するとなると Express と NestJS のどちらかかな、という感じになっていました。
どちらも実開発での経験を持っているメンバーはいなかったんですが、Web 開発で良く使われる Web フレームワークは、基本的な機能やコンセプトについては共通する部分が多いことに加えて、アカデミーも特殊な仕様があるプロダクトではないので、どちらを選んだとしてもメンバーが困ることはないだろうと考えました。
その上で細かい使い勝手などを検討したり GraphQL との親和性の高さや Express という枯れた技術をベースにしていて、フレームワーク自体の信頼感もあるので NestJS に決めたという感じでした。
熊本: 絞り込んだ段階で各メンバーが NestJS を試験的に触り、使用感を見てみましたが、大きく問題になる点もなかったので全員一致で決まった感じですね。
岸田: 前述のように Express をベースにしているので何か困ったら最悪 Express にすれば良いなというのもありました。
牧野: ここまで実際大きな問題というのは無かったです。
山田: 今は GraphQL を使って API を作っていると思いますが、REST で作るという選択肢は最初から無かったんですか?
岸田: はい、GraphQL を使えるメンバーが揃っているという状況であえて REST にするメリットは無いなという事で考えていませんでした。外部公開する API があるとか、パフォーマンスがすごく重要な重い API 呼び出しというのがあったら別だったでしょうけども。
山田: そもそもの話になってしまうんですが、弊社のプロダクト開発でよく使われている Ruby on Rails を使う選択肢は無かったんでしょうか?
岸田: 選択肢としてはあるにはあったんですが、プロダクトのフェイズとして現在既に成長をしているサービスであることや、メンバーのスキルセットとして Rails に慣れたメンバーがそこまで多くなかったことを考えると、いかに技術的負債を少なく保ちつつ、機能開発をしていけるかという点が重要になるので、現在の技術構成にしました。
これが既存サービスのリニューアルではなくて、新規で一から全部作っていかないといけないという状況であれば Rails を使うかもしれませんが、やっぱり型があってある程度開発効率が高くなるというのは魅力的だったので、これからどんどんと機能開発をするには今の構成が良いと判断しました。
山田: DB に関して PostgreSQL ですが、MySQL などにするということは考えなかったですか?
熊本: そうですね、リニューアル前のアカデミーが使っていたということがあり、大きく変えるメリットはあまり無かったのが大きいです。
岸田: あとこれは自分の感覚なのですが、PostgreSQL の方がスマートに処理できることが多いという印象があるというのもありました。
山田: 元々サービスで使っていたというのは、やっぱり大きいですね。ORM は Prisma ですよね。例えば他に TypeORM などの選択肢もあったと思いますが、こちらはどういった経緯で使うことになりましたか?
熊本: 色々と触ってみた結果、Prisma が自分たちの使い方にマッチしてたのが大きかったです。がっつりと SQL を自動生成するなどの手厚い機能は、自分達の使い方では必要もなかったですし。キャッチアップのためにペアプロなどもしましたが、メンバーも使いやすいということが確認できました。
山田: 今ペアプロの話が出ましたが、どのような目的でやっていたんでしょうか。
熊本: 初期の頃はメンバー間の知識などに偏りもあったので、そういったものを実際にコードを触りながら埋めていくという目的でした。実際に、GraphQL を使ったことがなかったメンバーも早く慣れてくれました。
山田: なるほど。ある種学習も兼ねていたんですね。最終的に現在このアーキテクチャの使い勝手としては感想としてどうでしょうか?
岸田: 言葉は違うかもしれないですが「普通に使い勝手が良い」という感じです。
もちろんメンバーが習熟してきたので、色々とコード的に改善しようという部分はあったりもしますが、今のところ本当に困った問題というのは無いので、非常に良い選択だったかと思います。
NestJS のテストコードについて
山田: テストコードは基本書いているんですよね?
熊本: はい、バックエンドは基本的に Jest で全部書いています。フロントエンドに関しては今まさに E2E テストをどのように実施していくかを試行錯誤しているところですね。
山田: NestJS でテストコード書くのに何か困ったこととかありましたか?
岸田: 困っているというわけではないですが、Rails でほぼ必ず使われている Factorybot に相当する機能が欲しいですね…。
山田: 確かに Node.js だとそういったライブラリを見かけないですね…。
岸田: 皆さんあんまり困ってないのかな?ということで今は簡易的なものを自作して使っています。
山田: OSS で作ったら需要があるかもしれませんね。
現状の NestJS での開発の課題感
山田: ここまで NestJS での開発について聞いてきましたが、プロダクト開発での課題は何かあったりしますか?
岸田: 先ほども少し話をしたメンバーの習熟度が高くなったことによるコード改善の他には、NestJS というか Node.js が Rails に比べると定番ライブラリが少なめなのがあります。
例えば、Sidekiq のようなライブラリって便利だと思うんですが、相当するライブラリでデファクトスタンダードというようなものが Node.js だと少ない気がしています。ライブラリが一杯あるのですが、デファクトまでいかないというものが多いという感想です。
山田: 確かに Node.js だと同じ目的のライブラリが複数あって機能がちょっとずつ違うという感じがありますね。
牧野: あとは機能開発にリソースを取っているので、細かい部分でのライブラリのアップデートが遅れ気味というのが課題感としてあります。
今のところはとてつもなく遅れているというわけではないのですが、積り積っていくとこういった部分が負債になっていくので、対応したいと思っています。
岸田: こういったものも含めてプロダクト開発を円滑に回すために、自分も含めた各メンバーのスキルを広げて深くしていかないといけないなというのもありますね。
チームへのオンボーディングについて
山田: さて、話が変わって現在アカデミーで一番最後にジョインしたのが徳永さんだと思いますが、オンボーディングなどはどのような感じだったんでしょうか。学生時代に NestJS はがっつり触っていたんでしたっけ?
徳永: いえ、学生時代はチュートリアルをしたくらいで、深く使っていたということはなかったです。ですので、最初は全然プロダクトのコードが分からないというレベルで、ほとんど未経験でした。
山田: なるほど。ほぼ未経験で新卒研修を経て、アカデミーの開発チームにジョインして困った部分などはありましたか?
徳永: TypeScript を使っているというのは凄く自分にとって良くて、言語でつまづくということはほとんどありませんでした。
やはり公式ドキュメントがすごく充実していますし、コミュニティの質の高い情報も多いので。プロダクトに関しては過去の Pull Request や Issue 上のやり取りなどで、どういう意図で実装されたものなのかを参照できたのが大きかったです。一方でバックエンドのデザインパターンなどは経験が少なく苦労した部分がありました。その部分はドキュメントで学習したり、周りのメンバーに直接質問しながらキャッチアップしていきました。
山田: 今年は入社後研修も TypeScript で書く割合が Ruby よりも多かったので、それがもし逆だったら、もっと苦労していたかもしれないですね。
徳永: そうですね、その可能性は十分にあり得ます。
山田: あとアカデミーチームは火水木に勉強会を開催していますよね。ジョブメドレーの開発チームでも噂になっています。
岸田: これは全員で集まる勉強会というわけではなく、月によって各自テーマを決めて火水木 1 時間ずつスキルアップのために時間を確保し、学んだことなどをアウトプットしていくという形式です。アウトプットしたものは、お互いに確認して知識を深めていこうというものですね。
山田: それは素敵な取り組みですね。あとは Figma で開発ドキュメントをまとめているのが印象的ですよね。
牧野: 最初は岸田さんが率先して、開発した部分のドキュメントなんかを書いていたんですが、最近はチームで共有するようなものもほとんど Figma でまとめるようになっています。
熊本: もちろん永続化しないといけないドキュメントは README なりコンフルエンスなりに書いていくのですが、ちょっとしたものを気軽に Figma にまとめられるのはすごく良いです。
岸田: 他の人がやっていることなんかも絶対に目につくので、そういった意味でもドキュメントが散らばらなくて今は良く機能していると思っています。
現状の課題感とアカデミーの開発に向く人
山田: 最後になりますが、アカデミーに来てほしい人材はどういった方でしょうか?
徳永: このプロダクトにわくわくできる方に来てほしいと思います。福祉業界に明るい方なんかは大歓迎です!
山田: なるほど。プロダクトのビジネス面の理解をして楽しんで開発できる方ですね。技術的な部分では何かありますか?
岸田: 今まで TypeScript と NestJS を中心に話していましたが、実はこれらができる人というのは必須条件ではありません。どの言語でもフレームワークでもちゃんと Web 開発が分かっている方であればという感じです。
他には情報感度が高い人が良いと思います。言語化が難しいのですが、開発環境や言語、ライブラリなどできちんと最新の情報が取捨選択できる方がいると、チームがより活性化すると考えています。
バックエンドでいうとベース部分などもきちんと手を入れることができて、なおかつ人に教えるのが好きな方が入ってもらえると、チームへの知識伝播などもより上手くいくと考えています。
あるとより良いなという所だと、現在アプリは React Native で作られているんですが、React Native でのアプリ開発に強い方だと嬉しいですね。ユーザーに一番使われているのはアプリなので、さらにそのユーザビリティなどを高めるためには、アプリ開発に強い方に入ってもらえるとありがたいです。
山田: よりアカデミーというプロダクトをドライブさせてくれる方にぜひ来てほしいところですね。本日はありがとうございました!
おわりに
メドレーの開発チームの中でも野心的なアーキテクチャで開発をしているアカデミーチームについてお伝えしました。
サービスを伸ばすために、適切に言語やフレームワークを選択していき、柔軟性を持って開発していってるんだなというのが伝わってきたインタビューでした。少しでも興味が出た方はぜひ、下のリンクからお話できればと思います!