[2021年版]トドケールで使っている技術について紹介します
みなさん、はじめまして。
トドケールで、プロダクトマネージャーをしています。@hayata-yamamoto です。最近、React, React Native のコードがある程度読めるようになり、「俺、天才かも」という全能感を味わいつつ仕事をしています。
さて、この度、トドケールではテックブログを開設し、定期的に技術発信をしていくことになりました。今回は、記念すべき最初の記事ということで、カジュアル面談等でよく聞かれる どんな技術を使っているのか? に答えていきます。
特段、変わった技術選定をしているわけではないのですが、それぞれにある程度意図があるため、それが伝われば嬉しいなと思っています。
どんな技術を使っているのか
弊社では、サーバーレスの技術を積極的に利用してサービスを開発しています。技術の全体像は画像のような感じです。以下では、「モバイル・フロントエンド」と「サーバーサイド・インフラ」の二つに分けて、それらの技術選定や現在の開発フローについて簡単に説明しようと思います。
モバイル・フロントエンド
開発方針
モバイルとフロントエンドの技術スタックは、React の恩恵を受ける形で選定されています。フロントエンド・モバイルアプリの開発方針は、現時点で以下のようになっています。
- React の恩恵を積極的に受ける
- React, React Native を使います
- JavaScript から TypeScript への移行を行う
- 重要度の高いところから段階的に進めています。
- プロジェクトのリファクタリングや、コンポーネント化は積極的に行う
- 開発効率を上げ、不具合・副作用の出にくい設計・実装には投資すべきと考えています
もともと、フロントエンドとモバイルアプリは、JavaScript が使用されていました。これは、サービスローンチ時に、開発速度を優先するための技術選定で、一定の納得感があるものだったと考えています。しかし、サービスを利用してくださる方が増え、開発者も増えていく中で、コードの共有を行う際に難しさを感じることが増えました。例えば、props に何が含まれているかを理解するために、他の実装を確認しなくてはならない、とか。さらに、プロダクト的には、プロトタイプ段階で作成したコードをリファクタリングする必要も出てきていました。
これらの背景を踏まえ、短中期的に見て JavaScript から TypeScript に移行した方が、効率的だと考えるようになりました。結果的に、今年の 6,7 月頃にフロント・モバイルの実装を TypeScript に全面的に移行することを決め、徐々に移行を進めています。現時点は、私の目算だと全体の 2, 3 割程度移行が完了しています。サービス上重要度の高い部分から対応を進めており、今後新しい実装を加える際に TypeScript で書き直すことをルールとしています。
より踏み込んだ技術の話
より詳細な話をしましょう。ウェブのフロントエンドは、Amplify を使ってホストされています。開発時には、Amplify が提供する Feature Branch Deployment を用いて、ブランチごとの環境を作成し、PR 上で実際に操作感を確認しながらレビューを行っています。GraphQL を用いていると書いていたため、Amplify の Backend を利用しているのでは?と思われた方もいらっしゃるかもしれませんが、Amplify でホストしているのはフロントエンドだけです。AppSync は後述する Terraform によって管理されています。(理由が気になる方は、ぜひカジュアルに...)
モバイルアプリは、ローカルでの開発段階から Expo を利用しています。これにより、実機での検証が行えるようにしています。プロダクトの特性上、カメラを使った操作が多く発生することもあり、Expo を利用することで開発が効率化されていると考えています。実機での検証が終わり、PR がマージされたらビルドしたファイルを TestFlight に配布して、社内でのテストを行う流れとなっています。
Amplify が最近、Next.js に対応したこともあり、TypeScript 移行が終わったらそっちにも移行できたらいいなぁとか、react-native-web も試してみたいなぁとか、色々思うところはあります。(やってくれる人がいたら、大変嬉しいと思ってます...)
サーバーサイド・インフラ
開発方針
サーバーサイド、インフラは Python, Terraform を用いつつ開発しています。開発方針は以下のようになっています。
- Python でも型の恩恵を適切に受けること
- Pydantic を用いた型を定義し、Lambda や APIGateway 内で利用しています
- REST API にロジックの実装は集中させていくこと
- GraphQL を薄くしていくことを意味します。BFF の文脈をイメージして設定しています。
- 積極的な自動化
- Terraform Cloud, Bitbucket Pipelines によるデプロイ自動化をしています
サーバーレスの技術を活用していることもあり、サーバーサイドとインフラの区別はあまり明確につけていません。強いて言えば、サーバーサイドアプリケーションは、Python で開発することにしています。これは、今後データが溜まってきたときに機械学習やデータ分析の恩恵を受けやすいという点を考慮して選定されています。
インフラを作成する際には、Terraform を用いています。Terraform のレジストリに公開されているモジュールを積極的に使用しています。また、リポジトリ設計に工夫をしており、リソースのユースケースごとにデプロイを切り分けられるようになっています。(これはいつか別の記事にします)
より踏み込んだ技術の話
前述の通り、アプリケーションは、Python を用いて開発しています。Serverless Framework を使ってアプリケーションのデプロイを行っています。Serverless Framework は内部的に CloudFormation に依存していることもあり、弊社のサーバーサイドは Terraform, CFn どちらも使っている状況になっています。現時点では、CI/CD に Bitbucket Pipelines を用いています。Serverless Dashboard の CI/CD の方が、Preview deployment ができたりして都合がいいのですが、まだ十分に試せていないというのが実情です。
また、開発時には、black, isort, flake8 など、モダンな Python の開発環境なら大体入っているツールは漏れなく入れているつもりです。テストは、unittest を使用しており、moto という AWS のリソースモックアップツールを多用しています。(moto はシミュレーターを立てるよりも楽にユニットテスト用のモックを作れるため、好んで使っています)
Serverless Framework では、Lambda と APIGateway、それに付随する少しのリソースを作成することにとどめ、残りのリソースの管理は Terraform で行うことにしています。必要になるリソース情報は、SSM のパラメータストアを有効活用し、Serverless Framework のデプロイ時に環境変数に詰め込むような運用をしています。(そうしないと、かなりデプロイ時に気を遣わなくてはならず、大変辛かったという背景があります...)
次に、Terraform ですが、前述の通りレジストリに公開されているモジュールを積極的に使っています。AppSync を提供する部分は、サーバーサイドの役割も担っています。Verocity Template Language (VTL) が Terraform で管理されていると思ってくれれば良いです。(これはそれなりにつらさもありますが...)また、デプロイ及びステート管理には Terraform Cloud を用いています。今まで、CircleCI や GitHub Actions, GitLab CI などで、自動デプロイを実装した経験からしても、Terraform のデプロイは Terraform Cloud を選んでおけば間違いないと言えるくらいよくできています。(導入がとても楽)
チームとしてはサーバーサイドとフロントエンドの責務をもっと明確に分け、サーバーサイドの汎用性を高めることを考えています。その文脈の中で AppSync(GraphQL) から APIGateway(REST) に徐々に移行中です。(また別の記事で詳しいことを書く予定です)
その他のツールたち
特に珍しいものはないと思います。強いて言えば、Autify を使っているところでしょうか。エンジニアリソースが潤沢にないスタートアップにとって、ビジネスサイドのメンバーと一緒に QA できる Autify にはメリットを感じています。いつかどこかで話せる機会があればいいな、と思ったりしてます。
おわりに
こんな感じでトドケールではプロダクトを開発しています。この記事を読んで、少しでも興味を持ってくれた人がいたら嬉しいです。
トドケールでは、一緒に働いてくれるエンジニアを募集しています!
Discussion