1つのリポジトリで2つのSpring Bootアプリを管理する
Webサービスを提供する場合、ユーザーにサービスを提供するためのフロントエンドと、データの閲覧や管理を行うためのバックエンドの2つWebアプリを作ることになると思います。 イートスマートでは、新規にWebサービスをつくる場合は主にSpring Bootを利用してます。 今回は、mavenのマルチモジュール機能を利用して、1つのリポジトリに2つのWebアプリを管理するようにしたことを書きたいと思います。
1つのリポジトリで管理する理由
今回のように2つのWebアプリがある場合、2つのリポジトリで管理する方法が一般的かもしれません。 もしくは、最初は1つのWebアプリでスタートして、その後2つ目のWebアプリが増えた場合など、リポジトリが2つになると思います。 今回は、最初から2つのWebアプリが必要ということがわかっていたことと、共通する処理を別途ライブラリやgitのサブモジュールで管理を行いたくなかったため、このようなかたちにしました。
mavenマルチモジュール
親プロジェクト内に子プロジェクトを含むことが出来ます。 今回は、以下のようにフロントエンド、バックエンド、共通の3つの子プロジェクトを作ります。
/parent ┣/frontend ┣/backend ┗/common
各ディレクトリには以下のようにpom.xmを作成します。
親ディレクトリのpom.xmは以下のようになります。 packagingへ"pom"指定し、子プロジェクトをmodules以下に定義します。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <groupId>multi-module-group-id</groupId> <artifactId>multi-module-artifact-id</artifactId> <packaging>pom</packaging> <modules> <module>frontend</module> <module>backend</module> <module>common</module> </modules> … </project>
frontendディレクトリのpom.xmlは以下のようになります。 まず、artifactIdとして、親pom.xmlのmodulesで定義した"frontend"を指定します。 つぎに、parentとして親pom.xmlで定義したgroupIdとartifactIdを指定します。 最後に、commonモジュールを依存に指定しています。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <artifactId>frontend</artifactId> <parent> <groupId>multi-module-group-id</groupId> <artifactId>multi-module-artifact-id</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>multi-module-group-id</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </dependency> </dependencies> … </project>
backendディレクトリのpom.xmlは、frontendディレクトリのものとほぼ同じです。 artifactIdに"backend"を指定します。
commonディレクトリのpom.xmlも、frontendディレクトリのものとほぼ同じです。 artifactIdに"common"を指定します。 frontend/backendと違い依存対象が無いので、記述していません。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>common</artifactId> <parent> <groupId>multi-module-group-id</groupId> <artifactId>multi-module-artifact-id</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> … </project>
Spring Bootアプリとして動かす
Spring Bootアプリとして動かすために必要なSpringApplication#runを実行するApplicationクラスは、frontend/backendそれぞれに作りました。 こうすることで、それぞれの環境に応じた初期化の処理を組み込むことが出来ます。
まとめ
以上の手順で、2つのSpring Bootアプリを管理することができるようになりました。 注意点として、Eclipse等で開発している場合、frontend/backendがそれぞれの処理を直接参照してしまう危険性があります。 これに関しては、現時点ではビルド時のテストで発見することで対処しています。