スタートアップの小規模Webサービスのリアルな技術スタック

#はじめに

[プレースホルダ](https://placeholder.co.jp/)というスタートアップのWebエンジニア兼マネージャーのAkahoriです。

弊社はエンジニアは10人以上いるものの、Webエンジニアは私含め3人ほどです。
3人のWebチームで、どのような理由で、どのような技術を使っているか、苦労している点などを共有します。

#サービス概要
先月、[リトルスパーク](https://litspk.com)というサービスをリリースしました。
子ども向けの、オンラインでの習い事プラットフォームで、先生と生徒をマッチングしています。
技術的にはいくつかの特徴を持ち、今回サンプルとして解説します。

* 授業はライブ授業のみで、お互いにZoomで行います。
* ZoomのIDは弊社で管理し、先生側、生徒側、双方が参加ボタン１つで参加できるようになっています。
* コース登録（審査有り）や日程登録、プロフィール更新などは全て先生が行うため、その仕組みがあります。

![スクリーンショット 2021-09-09 16.37.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310207/3b9c45a6-a500-c04f-ba41-8ca340d2a14d.png)


#言語・フレームワーク・ライブラリ
サーバーサイドもフロントエンドもTypeScriptで統一しています。
いくつかのメリットを感じています。

* 学習効率が上がる
* 使い回せるコードがある
* 型やデータのやりとりがしやすい

### フロントエンド
Next.jsを使っています。
弊社は元々はReact（CRA）を使っていたのですが、ルーティングの煩わしさと、SSR/SSGなどの技術が必要な場面が出てきたため、1年ほど前から切り替えています。

また、以下のようなライブラリを使っています。

* material-ui
コンポーネントのベースに利用

* dayjs
日付関連操作に利用

* formik
フォーム管理に利用

* yup
フォームのバリデーションに利用

* swr
データ取得・状態管理に利用

* [next-seo](https://www.npmjs.com/package/next-seo)
タイトルタグなどのSEO関連設定やOGPの設定に利用

* [fullcalendar](https://www.npmjs.com/package/@fullcalendar/core)
カレンダーコンポーネントとして利用

* [react-player](https://www.npmjs.com/package/react-player)
動画プレイヤーとして利用

* styled-components
スタイリングに利用

* storybook
個別コンポーネントのデザイン確認に利用

* [next/bundle-analyzer](https://www.npmjs.com/package/@next/bundle-analyzer)
バンドル内容の確認

### サーバーサイド
NestJSを使っています。
基本はExpressをコアにしたフレームワークで、スケーラブルなコードが書けます。

DBはMySQLを使っており、ORMとしてTypeScriptと相性の良いTypeORMを使っています。
最初はPrisma2を使っていましたが、トランザクション周りが微妙であったために移行しています。

また、以下のようなライブラリを使っています。

* moment
日付関連操作に利用

* [ical-generator](https://www.npmjs.com/package/ical-generator)
自動更新カレンダーの生成に利用

* passport
認証に利用

* [slack/webhook](https://www.npmjs.com/package/@slack/webhook)
slackへの通知に利用

* google-cloud　
GCPの操作に利用、@google-cloud/tasksと@google-cloud/logging-winstonを使っています

* [class-validator](https://www.npmjs.com/package/class-validator)
リクエストデータの検証に利用

* [class-transformer](https://www.npmjs.com/package/class-transformer)
レスポンスデータの変換等に利用

* googleapis
スプレでマスタを管理しているため、通信に利用

### 連携
REST APIで通信しています。
NestJSのソースから、Open APIの[ライブラリ](https://www.npmjs.com/package/@openapitools/openapi-generator-cli)でAPIクライアントを生成し、フロントではそれを利用することで型安全に通信ができています。

#利用した外部サービス

### Stripe
決済周りに利用しています。
APIはとても良くできているのですが、Stripe Connectという仕組みを使ったため、ここが複雑で非常に苦労しました。

Stripe Connectは、自社、消費者、以外の、サービス提供者などに送金できる仕組みです。
次のような特徴を持ちます。手数料もそれほど高くはないです。

* 簡易にサービス提供者の顧客確認（KYC）ができる
* 消費者の支払いから、サービス提供者への銀行振り込みまでAPIで完結できる

### Zoom
サーバーからZoom APIを叩いています。
ユーザーの作成やミーティングの作成を利用しています。
そこそこ複雑です。

### Cloudinary
画像の保管・加工・配信に利用しています。
パブリックな画像であれば、特定のURLから自動でリソースを紐づけることもできます。
この機能を利用し、メインの保管先であるGCPのCloud Storageから自動でアップロードしています。

### Sendgrid
メールの送信に利用しています。便利です。

#リポジトリ
monorepo構成を取っています。

ユーザー向けクライアント、サーバーアプリ、弊社管理用のクライアントの３つのアプリがあるのですが、一つのリポジトリで管理しています。
管理や全体の把握が容易なところや、連携しやすいというメリットがあります。

[lerna](https://github.com/lerna/lerna)というライブラリを使っており、基本便利なのですが、ライブラリのバージョンアップをする際などに煩わしい手順が必要になったりします。

#ディレクトリ

### クライアント
クリーンアーキテクチャ＋Atomic Designのような構成でやっていますが、全く厳密ではないです。

![スクリーンショット 2021-09-13 20.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310207/ba5a1567-b706-a394-0f62-4f5f11424781.png)

![スクリーンショット 2021-09-14 10.07.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310207/b13c7ce5-7038-aad4-7d9f-5e32ba94684e.png)


### サーバーサイド
クリーンアーキテクチャ＋NestJSの推奨、のような構成でやっています。

![スクリーンショット 2021-09-13 20.47.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310207/02cc5f0e-56d7-04e4-561f-587b36da6ceb.png)



#アーキテクチャ
全面的にGCPを使っています。
コストパフォーマンスと、複雑でない用途であれば使い勝手が良いことから選択しています。

まだ規模が大きくないため、シンプルな構成にしています。（矢印は適当です）

![Untitled Diagram (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310207/c6fa29da-16e6-b314-bffe-b798247a3113.png)

スタートアッププログラムも充実しています。
まだ利用されていない会社の方は是非検討いかがでしょう。

https://cloud.google.com/startup

#まとめ
大手以外ですと技術を公表しているプロジェクト・サービスは少ないですが、いかがでしたでしょうか。
何か一つでも、参考にしてもらえる箇所がありましたら嬉しく思います。

個別のライブラリ等についても随時見直しを行っているため、またしばらく経ちましたら更新した内容を公開したいと考えています。





#サービスを一緒に成長させるメンバー募集中です！
弊社では、エンジニアが楽しく効率的に働けることが生産性に直結するという考え方から、多くの裁量を持っています。
これより、「技術好きが楽しめる」会社であるかと考えています。

是非一度カジュアルにお話ししませんか？
正社員・業務委託、共に募集しています！
https://www.wantedly.com/projects/410613