Screenshot

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

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

ueokande/go-react-boilerplate Monolithic Go and React Application Boilerplate github.com

ボイラープレートの内容

このレポジトリには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