EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

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がそれぞれの処理を直接参照してしまう危険性があります。 これに関しては、現時点ではビルド時のテストで発見することで対処しています。