Skip to content

Fintan-contents/example-chat

Repository files navigation

SPA + REST API構成のチャットサービス コード例

SPA + REST API構成のサービス開発リファレンスが提供するコンテンツの1つです。 小さなチャットサービスを実装したコード例です。

このコンテンツの使い方

SPAやREST APIを開発するときに参考にして頂いたり、必要に応じてソースコードを流用して再利用して頂くことを目的としています。

GitHub上でソースコードを見て頂いたり、git cloneをしてローカルにソースコードを取得してテキストエディターやJavaのIDEで見て頂くことを想定しています。

トップレベルのファイル・ディレクトリの説明をします。

ファイル・ディレクトリ 説明
.ci CI用のスクリプトを格納しています
.gitlab GitLab上でマージリクエストを作成するときのテンプレートです
.gitlab-ci.yml GitLabでCI/CDするためのビルドパイプラインの設定ファイルです
README.md このファイルです
api-document REST APIのインターフェースを記述したOpenAPIドキュメントです
backend REST APIのソースコードです
docker Dockerを使用してローカルで動かすミドルウェアのための設定ファイルを格納しています
docker-compose.yml ローカルで必要なミドルウェアを動かすためのDocker Compose設定ファイルです
frontend SPAのソースコードです
notifier WebSocketで通知を行うアプリケーションのソースコードです(※SPAでもなくREST APIでもありませんが、WebSocketによる通知の例として参考にして頂けます)

本コンテンツはソースコードを参考にして頂くことは勿論ですが、GitLabでCI/CDを行う際に必要となるビルドパイプラインの設定なども参考にして頂くことも想定しています。

※本コンテンツはGitHubで公開していますが、開発自体はGitLabを用いて行っています

開発に必要なソフトウェア

本アプリケーションの開発には次のソフトウェアを使用しています。

ローカルで本アプリケーションを動かす場合はこれらソフトウェアのインストールをしてください。

また、必要に応じてテキストエディタやJavaのIDEをインストールしてください。

対象ブラウザ

本アプリケーションはGoogle Chromeを対象としています。 他の環境では動作しない可能性があります。

ローカルでの起動方法・停止方法

ローカルで本アプリケーションを動かすには大きくわけて次の4つを起動する必要があります(括弧内はソースコードのディレクトリです)。

  • データベースや外部サービスのモックなどのミドルウェア
  • REST API(backend
  • WebSocketで通知を行うアプリケーション(notifier
  • SPA(frontend

データベースや外部サービスのモックなどのミドルウェア

本アプリケーションでは次のような外部サービスを利用しています。 ※実際にサービスとして運用を行なっているわけではないので、AWSのマネージドサービスに関しては「実際にサービス運用をすると仮定した場合に利用するもの」と捉えてください

  • Amazon RDS for PostgreSQL
    • 永続化データの保持
    • ローカルではPostgreSQLで代替
  • Amazon ElastiCache for Redis
    • 認証前の一時的なユーザー情報の保持
    • 通知のためのキュー
    • ローカルではRedisで代替
  • Amazon S3
    • アップロードされた画像ファイルの保持
    • ダウンロードさせるためのチャットログの保持
    • ローカルではMinIOで代替
  • Amazon SES
    • ユーザーへ連絡するためのメール送信
    • ローカルではMailHogで代替

ローカル環境ではDockerおよびDocker Composeを利用することで、動作できるようにしています。

次のコマンドで起動してください。

$ docker-compose up -d

次のようにdocker-compose psコマンドを実行してStateUpになっていれば起動成功です。

$ docker-compose ps
         Name                        Command               State                       Ports                     
-----------------------------------------------------------------------------------------------------------------
example-chat_mail_1       MailHog                          Up      0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp
example-chat_minio_1      /usr/bin/docker-entrypoint ...   Up      0.0.0.0:9000->9000/tcp                        
example-chat_postgres_1   docker-entrypoint.sh postgres    Up      0.0.0.0:5432->5432/tcp                        
example-chat_redis_1      docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp 

停止する場合は次のコマンドを実行してください。

$ docker-compose down

REST API(backend)

REST APIをローカルで動かす場合、アプリケーションサーバとしてJettyを利用しています。

Mavenプラグインを利用しており、以下のようなコマンドを実行することで起動できます。

$ # backendディレクトリで実行してください
$ mvn jetty:run

初回の実行時はMavenリポジトリから依存するJARファイルをダウンロードするため、多少時間がかかります。

例外が発生することなく次のようなログが出力されると起動成功です。

[INFO] Started ServerConnector@114a18d6{HTTP/1.1,[http/1.1]}{0.0.0.0:9080}
[INFO] Started Server@75689d9c{STARTING}[10.0.0.alpha1] @6271ms

Hit <enter> to redeploy:

停止する場合はCtrl + Cを押してください。

Dockerコンテナで起動する場合

REST APIをローカルで動かす場合、Dockerコンテナで起動することもできます。

そのままDockerイメージを作成するとSameSite属性がNoneに設定されるようになっていますので、Cookieを送信するにはSecure属性をつける必要があり、HTTPS通信でなければCookieを送信することができなくなります。

ローカルでHTTP通信を使用して動作させたい場合は、Dockerイメージの作成前に、SameSite属性がLaxになるように設定を変更しておきます。

backend/src/main/jib/usr/local/tomcat/conf/context.xmlファイルを開き、CookieProcessorsameSiteCookies属性の値をlaxに変更します。

<Context>
  ...
  <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor" sameSiteCookies="lax"/>
</Context>

Dockerイメージは次のコマンドで作成します。Dockerイメージの名前はexample-chat-backendになります。

$ # backendディレクトリで実行してください
$ mvn package jib:dockerBuild -DskipTests

Dockerイメージが作成されているかどうかは、次のコマンドで確認することができます。

$ docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
example-chat-backend                 1.0.0      662b55a12169        50 years ago        466MB
example-chat-backend                 latest              662b55a12169        50 years ago        466MB

Dockerイメージが作成されたら、次のコマンドでDockerコンテナを起動します。Dockerコンテナ内から他のミドルウェアへはlocalhostでアクセスできないため、環境変数でミドルウェアの接続先を設定します。

docker run -it --rm -p 9080:8080 --network example-chat-network -e NABLARCH_DB_URL="jdbc:postgresql://postgres:5432/postgres" -e NABLARCH_LETTUCE_SIMPLE_URI="redis://password@redis:6379" -e MAIL_SMTP_HOST="mail" -e AWS_S3_ENDPOINTOVERRIDE="http://minio:9000" example-chat-backend:latest

例外が発生することなく次のようなログが出力されると起動成功です。

04-Sep-2020 07:55:36.952 情報 [main] org.apache.catalina.startup.Catalina.start サーバーの起動 [5,184]ms

停止する場合はCtrl + Cを押してください。

WebSocketで通知を行うアプリケーション(notifier)

WebSocketで通知を行うアプリケーションはREST APIと同様にローカルで動かす場合、アプリケーションサーバとしてJettyを利用しています。

次のコマンドで起動ができます。

$ # notifierディレクトリで実行してください
$ mvn jetty:run

例外が発生することなく次のようなログが出力されると起動成功です。

[INFO] Started ServerConnector@38eafdab{HTTP/1.1,[http/1.1]}{0.0.0.0:9081}
[INFO] Started Server@491cc0eb{STARTING}[10.0.0.alpha1] @4770ms

Hit <enter> to redeploy:

停止する場合はCtrl + Cを押してください。

既知の問題

まれにアプリケーション起動後、通知を行うと次のようなエラーになる場合があります。

java.lang.NoClassDefFoundError: Could not initialize class com.example.presentation.websocket.WebSocketNotifier

このエラーが発生し、解消されない場合は後述するDockerコンテナでの起動を試してください。

Dockerコンテナで起動する場合

WebSocketで通知を行うアプリケーションをローカルで動かす場合、Dockerコンテナで起動することもできます。

まず、次のコマンドでDockerイメージを作成します。Dockerイメージの名前はexample-chat-notiferになります。

$ # notifierディレクトリで実行してください
$ mvn package jib:dockerBuild -DskipTests

Dockerイメージが作成されているかどうかは、次のコマンドで確認することができます。

$ docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
example-chat-notifier                1.0.0      d3d0a0844ffb        50 years ago        454MB
example-chat-notifier                latest              d3d0a0844ffb        50 years ago        454MB

Dockerイメージが作成されたら、次のコマンドでDockerコンテナを起動します。Dockerコンテナ内から他のミドルウェアへアクセスするため、環境変数でミドルウェアの接続先を設定します。次のコマンドでは、ホスト端末(実行端末)を表すhost.docker.internalを使用して、localhostと同等の接続先に設定しています。

docker run -it --rm -p 9081:8080 --network example-chat-network -e NABLARCH_LETTUCE_SIMPLE_URI="redis://password@redis:6379" example-chat-notifier:latest

例外が発生することなく次のようなログが出力されると起動成功です。

04-Sep-2020 07:58:41.380 情報 [main] org.apache.catalina.startup.Catalina.start サーバーの起動 [3,314]ms

停止する場合はCtrl + Cを押してください。

SPA(frontend)

SPAはcreate-react-appを使用して開発しており、create-react-appの利用方法に則っています。

依存するライブラリをダウンロードするため、初回のみ次のコマンドを実行してください。

$ # frontendディレクトリで実行してください
$ npm ci

起動するには以下のようにnpm startを実行します。

$ # frontendディレクトリで実行してください
$ npm start

次のように出力されると起動成功です。

Compiled successfully!

You can now view example-chat-frontend in the browser.

  Local:            http://localhost:3000
  On Your Network:  http://192.168.0.19:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

更にnpm startは自動でブラウザを起動して http://localhost:3000 を開きます。

停止する場合はCtrl + Cを押してください。

動作確認をする

アプリケーションを触ってみてください。

本アプリケーションにはログイン認証機能があります。 あらかじめ用意しているユーザーの情報は次の通りです。

ユーザー名 メールアドレス パスワード
user1 user1@example.com pass123-
user2 user2@example.com pass123-

新しくユーザーを登録することも可能です。 ユーザー登録にはメールを使いますが、本アプリケーションをローカルで動かしている場合はメールサーバーのモックを使用します。 本アプリケーション内で送信されたメールを読む場合は、ブラウザで http://localhost:8025 を開いてください。

Docker Composeで起動しているミドルウェアへの接続方法

Docker Composeで起動しているミドルウェアへ接続するための情報はdocker-compose.ymlおよびdockerディレクトリ内のファイルに記載してあります。

PostgreSQLとRedisはDockerコンテナ内にCUIのクライアントツールが同梱されています。

PostgreSQLは次のコマンドで接続できます。

$ docker-compose exec postgres psql -U postgres

Redisは次のコマンドで接続した後にAUTHコマンドでパスワードを入力して認証を行なってください。

$ docker-compose exec redis redis-cli

MinIOとMailHogはDockerコンテナ内にGUIのクライアントツールが同梱されています。 いずれもウェブアプリケーションです。

MinIOのクライアントツールを使うにはブラウザで http://localhost:9000 を開いてください。

MailHogのクライアントツールを使うにはブラウザで http://localhost:8025 を開いてください。

その他

静的解析

REST API(backend)・WebSocketで通知を行うアプリケーション(notifier)

REST APIとWebSocketで通知を行うアプリケーションはNablarchが提供しているJavaスタイルガイドを参考にして静的解析を組み込んでいます。

SpotBugsによる静的解析をMavenで実行できます。 次のコマンドでチェックできます。

$ # backendディレクトリ、またはnotifierディレクトリで実行してください
$ mvn spotbugs:check

SPA(frontend)

SPAはESLintによる静的チェックが行えるようにしています。

次のコマンドでチェックできます。

$ # frontendディレクトリで実行してください
$ npm run lint

内容によっては機械的に修正が可能なものもあります。 そういったものは、次のコマンドで修正することが可能です。

$ # frontendディレクトリで実行してください
$ npm run lint:fix

テストの実行

REST API(backend)・WebSocketで通知を行うアプリケーション(notifier)

JUnitを使ったテストコードを用意しています。

次のコマンドでテストを実行できます。

$ # backendディレクトリ、またはnotifierディレクトリで実行してください
$ mvn test

mvn testで実行されるものはミドルウェアを使用しない箇所に対するテストになります。

ミドルウェアを使用する箇所に対するテストは次のコマンドで実行できます。なお、ミドルウェアを使用するため、事前にDocker Composeでミドルウェアを起動しておく必要があります。

$ # backendディレクトリ、またはnotifierディレクトリで実行してください
$ mvn verify

SPA(frontend)

次のコマンドでテストを実行できます。

$ # frontendディレクトリで実行してください
$ npm test

※ このリポジトリはApache License Version 2.0の下に提供されています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

※ AWS、Amazon RDS for PostgreSQL、Amazon ElastiCache for Redis、Amazon S3、Amazon SESは、米国および/またはその他の諸国における、Amazon.com, Inc.またはその関連会社の商標です。

About

SPAとREST APIで構成される小さなチャットアプリケーションの実装例です。

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors