演習 - Azure リソースと Java Spring アプリケーションを作成する

完了

このユニットでは、基本的な Spring Boot アプリケーションを作成します。 Azure CLI と任意の統合開発環境 (IDE) を使用して、コードを編集します。 任意のターミナルを使用して、コードを実行します。

作業環境を準備する

以下のコマンドを使用して、いくつかの環境変数を設定します。

AZ_RESOURCE_GROUP=azure-spring-workshop
AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
AZ_LOCATION=<YOUR_AZURE_REGION>
AZ_MYSQL_USERNAME=spring
AZ_MYSQL_PASSWORD=<YOUR_MYSQL_PASSWORD>
AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>

コード内で、プレースホルダーを、次の表の値に置き換えます。 これらの値は、このモジュール全体で使用されます。

変数 説明
<YOUR_DATABASE_NAME> MySQL サーバーの名前。 Azure 全体で一意である必要があります。
<YOUR_AZURE_REGION> 使用する Azure リージョン。 既定では eastus を使用できますが、居住地に近いリージョンを使用することをお勧めします。 使用できるリージョンの完全な一覧を表示するには、「az account list-locations」と入力します。
<YOUR_MYSQL_PASSWORD> MySQL データベース サーバーのパスワード。 パスワードは少なくとも 8 文字にする必要があります。 次のうち 3 つのカテゴリから文字を選択する必要があります:英大文字、英小文字、0 ~ 9 の数字、英数字以外の文字 (!、$、#、% など)。
<YOUR_LOCAL_IP_ADDRESS> Spring Boot アプリケーションを実行するローカル コンピューターの IP アドレス。 この IP アドレスを見つけるには、ブラウザーで whatismyip.akamai.com を参照してください。

次に、リソース グループを作成します。

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    | jq

Note

このモジュールでは、jq ツールを使用します。これは、JSON データを表示して読みやすくするために、既定で Azure Cloud Shell にインストールされます。

jq ツールを使用したくなければ、このモジュールのすべてのコマンドの、| jq の部分を安全に削除できます。

Azure Database for MySQL のインスタンスを作成する

ここでは、マネージド型の MySQL サーバーを作成します。

注意

Azure Database for MySQL の詳細については、このモジュールの最後で、関連ドキュメントへのリンクを参照してください。

次のスクリプトを実行して、Azure Database for MySQL の小さなインスタンスを作成します。 データベースは、1 つの CPU と 2 GB の RAM を備えています。

az mysql server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --sku-name B_Gen5_1 \
    --storage-size 5120 \
    --admin-user $AZ_MYSQL_USERNAME \
    --admin-password $AZ_MYSQL_PASSWORD \
    | jq

このスクリプトでは、前に設定した変数を使用する小さな MySQL サーバーを作成します。

MySQL サーバーのファイアウォール規則を構成する

既定では Azure Database for MySQL はセキュリティで保護されています。 そのファイアウォールでは、着信接続を許可しません。 そのため、ローカル IP アドレスに、データベース サーバーへのアクセスを許可するファイアウォール規則を追加します。

次のコマンドを実行してサーバーのファイアウォールを開きます。

az mysql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip \
    --server-name $AZ_DATABASE_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    | jq

次のコマンドを実行して、Azure リソースからのファイアウォール アクセスを許可します。

az mysql server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name allAzureIPs \
    --server-name $AZ_DATABASE_NAME \
    --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0 \
    | jq

MySQL データベースを構成する

先ほど作成した MySQL サーバーは空です。 そこに、Spring Boot アプリケーションで使用できるデータベースはありません。 demo という新しいデータベースを作成します。

az mysql db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server-name $AZ_DATABASE_NAME \
    | jq

Spring Initializr を使用してアプリケーションを生成する

Spring Initializr は、ユーザーのために Spring Boot プロジェクトの構造を生成する Web アプリケーションです。 Spring Initializr ではアプリケーション コードはまったく生成されませんが、基本的なプロジェクト構造と、Maven のビルド仕様が提供されます。

3 つの依存関係 webmysqldata-jpa を使用してアプリケーション スキャフォールディングを生成します。 アプリケーションはローカルで実行する予定であるため、Azure の依存関係を指定する必要はありません。

コマンド プロンプトで、アプリケーションを生成します。

curl https://start.spring.io/starter.tgz -d type=maven-project -d dependencies=web,data-jpa,mysql -d baseDir=azure-spring-workshop -d bootVersion=3.1.5.RELEASE -d javaVersion=17 | tar -xzvf -

Azure Database for MySQL を使用するように Spring Boot を構成する

src/main/resources/application.properties ファイルを開き、いくつかのプロパティを追加します。 必ず、2 つの $AZ_DATABASE_NAME 変数と $AZ_MYSQL_PASSWORD 変数を、前に設定した値に置き換えてください。

logging.level.org.hibernate.SQL=DEBUG

spring.datasource.url=jdbc:mysql://$AZ_DATABASE_NAME.mysql.database.azure.com:3306/demo?serverTimezone=UTC
spring.datasource.username=spring@$AZ_DATABASE_NAME
spring.datasource.password=$AZ_MYSQL_PASSWORD

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop

警告

構成プロパティ spring.jpa.hibernate.ddl-auto=create-drop は、アプリケーションの起動時に Spring Boot によってデータベース スキーマが自動的に作成され、シャットダウン時にデータベース スキーマの削除が試みられることを意味します。 このプロパティはテストには便利ですが、運用環境では使用してはいけません。

注意

構成プロパティ spring.datasource.url?serverTimezone=UTC を追加します。 この設定で、データベースへの接続時に、世界協定時 (UTC) の日付形式を使用するように Java Database Connectivity (JDBC) ドライバーに指示します。 そうしないと、Java サーバーでデータベースと同じ日付形式が使用されず、エラーが発生する結果になります。

次に、提供されている Maven ラッパーを使用してアプリケーションを起動します。

./mvnw spring-boot:run

このスクリーンショットは、初回実行時のアプリケーションを示しています。

実行中のアプリケーションを示すスクリーンショット。

アプリケーションをコーディングする

次に、下記の Java コードを追加します。 Java Persistence API (JPA) を使用して、MySQL サーバーとの間でデータの格納と取得を行います。

JPA エンティティ クラスを使用して、Java Todo オブジェクトを MySQL Todo テーブルに直接マップします。

DemoApplication クラスの横に、新しい Todo エンティティ クラスを作成します。 次のコードを追加します。

package com.example.demo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Todo {

    public Todo() {
    }

    public Todo(String description, String details, boolean done) {
        this.description = description;
        this.details = details;
        this.done = done;
    }

    @Id
    @GeneratedValue
    private Long id;

    private String description;

    private String details;

    private boolean done;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public boolean isDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Todo)) {
            return false;
        }
        return id != null && id.equals(((Todo) o).id);
    }

    @Override
    public int hashCode() {
        return 31;
    }
}

このクラスは、Todo テーブルでマップされているドメイン モデルです。 これは、JPA によって自動的に作成されます。

このクラスを管理するにはリポジトリが必要です。 同じパッケージ内に新しい TodoRepository インターフェイスを定義します。

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;

public interface TodoRepository extends JpaRepository<Todo, Long> {
}

このリポジトリは、Spring Data JPA によって管理される JPA リポジトリです。 JpaRepository を拡張して、型に対して汎用の作成、読み取り、更新、削除 (CRUD) の一連のメソッドを取得します。 そうすると、Todo オブジェクトの保存や削除などのことができます。

HTTP を使用してデータの格納と取得を行う REST インターフェイスを公開できる RestController を作成して、アプリケーションを完成させます。 同じパッケージ内に TodoController クラスを実装します。 次のコードを追加します。

package com.example.demo;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/")
public class TodoController {

    private final TodoRepository todoRepository;

    public TodoController(TodoRepository todoRepository) {
        this.todoRepository = todoRepository;
    }

    @PostMapping("/")
    @ResponseStatus(HttpStatus.CREATED)
    public Todo createTodo(@RequestBody Todo todo) {
        return todoRepository.save(todo);
    }

    @GetMapping("/")
    public Iterable<Todo> getTodos() {
        return todoRepository.findAll();
    }
}

最後に、次のコマンドを使用して、アプリケーションを停止し、もう一度起動します。

./mvnw spring-boot:run

Spring Boot アプリケーションが起動し、データベースに接続されるはずです。

このスクリーンショットは、データベースに接続しているアプリケーションを示しています。

データベースに接続している実行中のアプリケーションを示すスクリーンショット。

アプリケーションをテストする

アプリケーションをテストするには、cURL を使用できます。

まず、データベース内に新しい Todo 項目を作成します。

curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done": "true"}' \
    http://127.0.0.1:8080

次のコマンドを実行すると、作成した項目が返されます。

{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}

次に、新しい cURL 要求を使用してデータを取得します。

curl http://127.0.0.1:8080

このコマンドを実行すると、作成した項目を含め、Todo 項目の一覧が返されます。

[{"id":1,"description":"configuration","details":"congratulations, you have set up your Spring Boot application correctly!","done":true}]