見出し画像

自社WebプロダクトをServerless Framework+OpenAPI+Nuxt+TypeScriptでごっそり作り変えた話

TL;DR
・開発中はたくさんバグが出たが、リリース後は意外と何もなかった
・リプレイス後の開発スピードが劇的に(当初の予想より更に)向上した
・プロジェクトメンバーのスキルが大きく向上した
・プロダクトに対する理解が数段深まった

はじめまして、エン・ジャパンでWebエンジニアをやっている松田と申します。

突然ですが、皆さんは作り直したいアプリ・プログラムはありますか?
エンジニアという職業柄、思っている方もかなり多いとは思いますが、時間的・ビジネス的な理由で実行できないこともまた多いと思います。

今回、開発チームに対して「リプレイスして良いよ〜」との非常にありがたい許可が下りたので、メンバーができること・やりたいことを全部やって全力で作り直しました。

リプレイスを検討されている方のご参考になれば幸いです。

Video Interview(リプレイスしたWebアプリ)の紹介

作り直したのは、Video InterviewというWebアプリになります。

Video Interviewを一言で説明すると、採用担当者向けの録画面接ツールです。
企業側は面接の質問を動画で録画でき、応募者に招待メールを送ることができます。
応募者側は企業側の質問動画を再生して、自身の回答を録画して提出することができます。

ZoomやSkypeなどのチャットアプリと違って、録画した動画で非同期的にやり取りするので、

・採用担当者は自身の時間を取られることがなく、効率的に応募を精査できる
・応募者は好きな場所・時間で回答できるので、通常の面接のようなタイムスケジュール管理が不要になる

など、双方にとってメリットがあります。
また、アプリは全てブラウザ上で動作するので、インストールなども不要です。

詳しくはLPをご覧下さい。

アプリのログインページから、無料でお試し頂けるので、是非サインアップして使ってみてください!

主な機能は以下のような感じです。

企業側
・面接の作成/編集
・質問動画の撮影/編集
・面接への招待メールの送信
・面接用の公開リンクの発行
・応募者の回答動画の閲覧/合否、評価の設定

応募者側
・面接の受験、質問動画の視聴
・回答動画の提出

リプレイス前のアーキテクチャと問題点

リプレイス前のアーキテクチャは大体以下のような感じでした。

・バックエンド、データストア: Firebase
・フロントエンド(Webアプリ): React+Redux
・フロントエンド(スマートフォン): React Native
・ダッシュボード: React+Redux
・動画のエンコーディング: Amazon Elastic Transcoder
・メール送信サービス: Mailgun
・SMS送信サービス: Twilio

決してレガシーなシステムではなく、というかむしろめちゃくちゃ先進的で、バックエンドはFirebaseオンリー、フロントエンドはReactReact Nativeという尖りっぷりでした。

ただ、当時の主要メンバーが離れてしまったこともあり、保守のために入ったメンバーはかなり辛い状況でした。
具体的には以下のような問題点がありました。

Firebase関連の問題
Realtime Databaseにリレーション用のデータを作る必要があり、データ全体が混沌としていた
Firebase Rulesを使ってデータの整合性を管理する必要があるが、機能していないルールもあり、どこまで有効かわからなかった
Realtime DatabaseはBIツールと相性が悪く、分析が難しいため、プロダクトの戦略が立てづらかった
・ダッシュボードのアプリでは毎回全データを取得する必要があり、操作できるようになるまで数分かかった

React関連の問題
Reactのメジャーバージョンに追従できていなかった(2つほど離れている)
React+Redux(あとRedux-Sagaも使ってた)こともあって、アプリの規模に対してコードが分割され過ぎていて追うのが辛かった
・当時のメンバーのスキルがめちゃくちゃ高く、独自実装が多くて改修難易度が高かった
React Nativeがわかるメンバーがおらず、リリース手順もわからなかったためスマホ版は実質保守できていなかった
・Webアプリ用とスマホアプリ用の共通ロジック(ReactReact Nativeなのでそういうことができる)をメンテするのがしんどかった

その他の問題
・動画のエンコーディング処理だけKotlinで実装されており、メンバーのスキルセット的に改修難易度が高かった
・バックエンド、フロントエンド共にJavaScriptで実装されており、暗黙的な型変換に起因した不具合もいくつか発生していた。

リプレイス後のアーキテクチャと改善点

問題点を改善するため、リプレイス後のアーキテクチャは以下のようになりました。

・Webフレームワーク: Serverless Framework
・APIインターフェース: OpenAPI(Swagger)
・バックエンド: AWS Lambda(Node.js+TypeScript)
・データストア: Amazon RDS(PostgreSQL)
・フロントエンド(Webアプリ): Nuxt.js(Vue.js+TypeScript)
・フロントエンド(スマートフォン): 不要(ブラウザ上で動作するようになったため)
・ダッシュボード: Re:dash(必要最小限の機能はNuxt.js)
・ 動画のエンコーディング: Amazon Elastic Transcoder(TypeScript)
・メール送信サービス: Amazon SES
・SMS送信サービス: Amazon SNS

これらのアーキテクチャの変更によって、問題点が以下のように改善されました。

Firebase関連の問題

Realtime Databaseにリレーション用のデータを作る必要があり、データ全体が混沌としていた
Firebase Rulesを使ってデータの整合性を管理する必要があるが、機能していないルールもあり、どこまで有効かわからなかった
Realtime DatabaseはBIツールと相性が悪く、分析が難しいため、プロダクトの戦略が立てづらかった
・ダッシュボードのアプリでは毎回全データを取得する必要があり、操作できるようになるまで数分かかった

Amazon RDS(PostgreSQL)によってリレーション・データの整合性が保証されるようになった
・ダッシュボードとしてRe:dashを導入したことで、ダッシュボードをすべて作り直す必要がなくなり、ディレクターの方にSQLをサラッと書いてもらうだけで分析ができるようになった


React関連の問題

Reactのメジャーバージョンに追従できていなかった(2つほど離れている)
React+Redux(あとRedux-Sagaも使ってた)こともあって、アプリの規模に対してコードが分割され過ぎていて追うのが辛かった
・保守メンバーのReactスキルが、相対的に低かった(というか当時のメンバーのスキルがめちゃくちゃ高かった)
React Nativeがわかるメンバーがおらず、リリース手順もわからなかったためスマホ版は実質保守できていなかった
・Webアプリ用とスマホアプリ用の共通ロジック(ReactReact Nativeなのでそういうことができる)をメンテするのがしんどかった

Nuxt.jsの最新バージョンを導入し、追従も積極的に行っている
・コンポーネントの数も適度に減らしてメンテし易くなった
・メンバーのスキル的に、誰でもフロントを改修できる状態になっている
・スマートフォンでもカメラを起動するようにUI/UXを見直したことで、Webアプリだけでフロントをカバーできるようになり、開発スピードが向上した


その他の問題

・動画のエンコーディングがなぜかKotlinで実装されており、メンテするのがしんどかった
Mailgun(メール送信サービス)の知見があるメンバーがいなくてしんどかった
Twilio(SMS送信サービス)の知見があるメンバーがいなくてしんどかった
・バックエンド、フロントエンド共にJavaScriptで実装されており、保守がしんどかった

・インフラはすべてAWSに寄せたので管理が楽になり、情報も得易くなった
・フロント・バックエンドともにすべてTypeScriptで実装したことにより、型安全に開発を進められるようになった


また、上記の改善点以外にも、エンジニアが積極的に取り入れたアーキテクチャによって以下のようなメリットも得られました。

Serverless Frameworkによってリソースをすべてコードで管理(いわゆるIaaS)できるようになり、保守性が大きく上がった
OpenAPI(Swagger)によってバックエンド・フロントエンドでモデル、バリデーション、リクエスト、レスポンス関連のコードの大部分を生成できるようになり、開発効率が上がった

開発中の出来事

開発期間は2019年8月〜2020年6月までの11ヶ月ですが、色々なことがありました。
せっかくなので、時系列順に振り返っておこうと思います。

2019年
8〜9月
・技術選定
・要件定義
・DB定義
・開発計画の作成
・開発環境構築
・既存アプリの改修

この頃は一番メンバーのテンションが高かったかもしれないです。
どんな技術を使うかを皆で楽しく話したりしながら、リリースまで余裕でしょって雰囲気が漂ってました。

10月〜11月
・バックエンド叩き台作成
・フロントエンド叩き台作成
・API定義
・要件の見直し
・既存アプリの改修

それぞれのメンバーで分担して、各タスクをこなしていました。
この頃はまだブラウザ上でスマホにどういう流れで動画を撮影させるか決まってなかったりしました。

12月
・バックエンド実装
・フロントエンド実装
・データ移行スクリプト叩き台作成

やっと実装に入りましたが、早々に辛さが見えてきた時期です。
OpenAPI(Swagger)のコードジェネレータの仕様でコードを見直す必要が出てきたり、モデルの構成を変えたりと、主にバックエンドで見直しが多く発生しました。

ちなみに、自分はデータ移行スクリプトの叩き台を作りましたが、Firebaseで全データ取ってきて各テーブルに入れていくのは地味にしんどかったです。
開発中の変なデータが見つかってはスクリプトが止まっての繰り返しでした。

2020年
1月〜3月

・バックエンド実装
・フロントエンド実装

本格的な実装の時期でした。
また、当初のリリース予定日は5月中頃だったこともあり、この頃には初期の余裕は完全に消滅していました。

4〜6月
・データ移行スクリプト作成
・結合テスト・システムテスト・不具合改修
・リリース

バックエンドとフロントエンドを繋いでの結合テストが始まりましたが、想定よりも多くの不具合が発生したため、当初のリリース日の5月から1ヶ月延長する方針になりました。
主な不具合の原因は、メンバーの作業分担に失敗してフロントエンドメンバーの負担が多くなってしまい、色々と実装が漏れてしまったことや、各メンバーの負担が増えてしまい、十分なレビューができなくなってしまっていたことでした。

この時期にデータ移行のスクリプトがすべて作られました。DBのデータ以外にも、Firebaseの認証情報・動画・動画のサムネイルなど全てのデータが移行されるようになりました。

また、この時期からコのつく例のウィルスが猛威を振るい出して、弊社でもリモートワークとなりました。
幸いメンバーの全員が問題なく対応できたので、開発には支障は出ませんでした(むしろ効率が上がって助かりました)。

更に、4/15にChrome 81のバージョンアップに伴う変更が原因で、しばらく開発を止めていた既存のアプリを動かなくなるトラブルが発生しました。
この日はメンバー総出で1日かけて直しました。今思い返してみても、皆さんには本当に感謝したいです。

そんなこんなで紆余曲折を得て、6/14(日)、今まで稼働していたVideo Interviewというアプリは、データ・バックエンド・フロントエンドがごっそり入れ替わり、リプレイスが無事完了しました。

リプレイスが終わってから1ヶ月経ちますが、驚くくらいに不具合が見つかっていないです。
リリース前まで根気強くテストと改修を繰り返したのが理由だと思いますが、これだけの規模のリプレイスで不具合が出なかったのは自慢できる気がします。

まとめ

リリースまでを振り返ってみましたが、苦労した分報われた気がします。
改めまして、
・リリースまで舵を取ってくださったプロダクトマネージャのKさん
・インフラ・バックエンドの面倒を見てくださったMさん
・フロントエンドをガンガン実装してくださったYさん
・既存の開発を兼任しながら、データ移行も担当してくださったHさん
・途中参加だったのを忘れるくらい既存メンバーと同等以上のスピードで開発してくださったSさん
・新人でこんな大変なプロジェクトに参加したにも関わらず、即座に適応してくれたKさん
本当にありがとうございました。
自分の今までのエンジニア人生で一番良い開発チームでした。

リプレイスによって生まれ変わったVideo Interviewは、以前では不可能だった改修も平気でできるようになり、開発スピードも段違いになりました。
開発メンバーが今回のリプレイスの中で様々な経験をして、スキルが大きく向上したのも開発スピード向上に寄与していると思います。
また、リプレイスの中で全メンバーがアプリの仕様を考える機会に恵まれたことで、今後のアプリの機能追加・改修に関する議論が活発化するようになったのも嬉しい副作用でした。

リプレイス後はスクラム開発するようになり、毎日楽しく開発しています。
今後更に楽しく開発できるようになることを願いつつ、締めたいと思います。
改めまして、ここまで読んで下さった方、本当にありがとうございました。

一緒に働きたいメンバー募集中です

エン・ジャパンでは、一緒に働く仲間を募集しています。
採用情報は下記よりご確認ください。


みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!