GoとReactでモノリスアプリケーションを作る

GoとReactでモノリスアプリケーションを作る

現在の Web サービスは、ビジネス要件や信頼性、スケーラビリティなどの理由で、構築方法やプラクティスが多様化しています。 マイクロサービスやマイクロフロントエンドは、巨大なサービスや巨大なチームを、自己組織的なチームに分割してそれぞれがサービスをメンテナンスできる体制を実現するプラクティスです。 これらの手法は、開発サイクルを向上するだけでなく、サービスをより持続可能な体制を作ることができます。 しかしこれらの仕組みは成長するサービスには有用ですが、複雑なアーキテクチャは複雑な開発やデプロイをもたらします。 社内サービスなどのビジネスクリティカルでないものには少し過剰なときがあります。

そこで Go と React でお手軽に小さなモノリス Web サービスを作成できるボイラープレートを作りました。

ボイラープレートの内容

このレポジトリには Go で書かれたサーバーと、React を使ったフロントエンドで構成される、シンプルでモノリシックなサービス提供します。 このサービスはマイクロサービスやマイクロフロントエンドのようなモダンなサービス向けではありませんが、簡単に開発やデプロイができます。

このサービスは以下の技術スタックを採用しています。

このサービスは例として小さなソーシャルブログを提供し、ユーザーは記事の公開や記事に対するコメントを追加できます。

クリックスタート

このレポジトリはサーバーサイドのコードとフロントエンドのコード両方を含みます。 フロントエンドはfrontendディレクトリに格納されており、yarnコマンドで依存ライブラリのインストールとデバッグザーバーを起動できます。

$ cd frontend
$ yarn install && yarn start

そしてサーバーサイドはgo runコマンドで起動できます。

$ go run main.go  -debug

すると Web ブラウザで http://localhost:8000 を開くと、実際にアプリケーションを触ることができます。

サンプルアプリケーションの解説

このアプリケーションは小さなソーシャルブログです。 Web ブラウザから、記事の閲覧や公開できます。 また記事に対するコメントなども書き込むことができます。

フロントエンドのページはシングルページアプリケーションとして、1 つのページで構成されており、サーバーサイドプログラムは単一の HTML のみを返します。 フロントエンドの JavaScript は、記事やコメントの取得と送信をaxiosを使って非同期 API でやり取りします。 サーバーサイドアプリケーションは以下の API を提供します。

  • GET /api/healthGET /api/ready: これはサービスが稼働しているかどうかのエンドポイントです。詳細はKubernetes のドキュメントを参照してください。
  • GET /api/articles: すべての記事の概要を取得します。
  • GET /api/articles/{article_id}: 単一の記事の全文を取得します。
  • POST /api/articles: 新しい記事を公開します。
  • GET /api/articles/{article_id}/comments: 記事に対するコメントを取得します。
  • POST /api/articles/{article_id}/comments: 記事に対してコメントを送信します。

開発方法

サーバーサイドプログラムをデバッグモードで起動すると、Webpack デバックサーバーを同じエンドポイントで提供します。 これはフロントエンドの JavaScript が CORS ヘッダーの準備なしに API へアクセスできます。 /api/ 以外のエンドポイントは、HTML、JavaScript、CSS を返します。

サーバーサイド

サーバーサイドは 2 つのパッケージrepositorywebを持ちます。 repositoryパッケージはユーザーデータの読み込みと保存をするインターフェスと実装を含みます。 このサンプル実装ではサーバーはデータを永続化せず、再起動時にデータは失われます。 もしデータを永続化したい場合は、in-memory のモック実装ではなく MySQL などに保存する実装を書いてみてください。

webパッケージはリクエスト URL から経路を設定してユーザーにデータを返します。 これは MVC や DDD で言うところのコントローラー層に近いです。 もし API やモデルを追加する場合は、repositorywebに追加してください。 またより複雑なロジックやユースケースを追加する場合は、更にパッケージを追加しても良いです。

フロントエンド

すべてのページはシングルページアプリケーションとして、単一のページが提供されます。 react-routerはクライアントサイドでルーティングできるライブラリです。

フロントエンドのコードはreact-scriptsをもとに初期化しており、ディレクトリ構造とビルドプロセスは維持してあります。 またすべてのコンポーネントは frontend/src 以下にフラットに配置してあります。

本番環境へのデプロイ

手動デプロイ

本番環境では yarn startgo run を使ってサービスを提供すべきではありません。 デプロイ前にビルドする必要があります。 フロントエンドのアセットはyarn buildで作成できます。 このコマンドは minify された HTML、JavaScript、CSS を生成します。

$ (cd frontend && yarn install && yarn build)

サーバーサードアプリケーションのコンパイルは go build でできます。

$ CGO_ENABLED=0 go build -o go-react-boilerplate -trimpath .

そしてサービスは以下のコマンドで起動します。

./go-react-boilerplate -webroot ./frontend/build

サーバーサイドアプリケーションは -webroot で指定したアセットを返すことも出来ます。 そのため Apache HTTP サーバーや NGINX のような 3rd パーティーの Web サーバーを新たにインストールする必要がありません。

Docker コンテナのビルド

このレポジトリはDockerfileも含んでいます。 Docekr コンテナを使うと、より開発やデプロイが容易になります。 Dockerfile は multi-stage ビルドで構成され、フロントエンド、バックエンドのビルドが出来ます。 docker build および docker run コマンドでコンテナイメージのビルドと、コンテナの起動ができます。

$ docker build -t go-react-builderplate .
$ docker run --rm -p 8000:8000 go-react-builderplate

Profile picture

Shin'ya Ueoka

B2B向けSaaSを提供する会社の、元Webエンジニア。今はエンジニアリング組織のマネジメントをしている。