Spring Boot WEBサービスの Hello World!

# Spring Boot WEBサービスの Hello World!

## 目的

Spring Boot で最小構成のWEBサービスを作成して理解を深めます。  

## 実現すること

ローカル環境 (Ubuntu) で Spring Boot jar ファイル形式のアプリをビルド・起動します。

## 技術背景

### Spring Boot とは？  

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### [Spring Boot](https://spring.pleiades.io/spring-boot/docs/2.7.8/reference/html/getting-started.html#getting-started)

Spring Boot は、Java で Web アプリケーションを開発するためのフレームワークの一つで、Spring Framework をベースにしたライブラリの集合体です。  

特徴としては、以下のような点が挙げられます。  

+ 設定が簡単で、コードを書くだけで Web アプリケーションを作成できます。
+ アプリケーションの自動構成や自動検出などの自動化された機能を備えています。
+ Spring Framework の依存関係を自動的に解決するため、開発者はライブラリの管理に時間を費やすことがありません。
+ 多様なデータソースやセキュリティ機能などの多くのライブラリをサポートしているため、柔軟性が高く、多くの用途に使えます。
+ アプリケーションをマイクロサービスとして実行するための Spring Cloud という拡張も提供されています。

メリットとしては、以下のような点が挙げられます。  

+ 開発者はアプリケーションのビジネスロジックに集中でき、煩雑な設定やセットアップに時間を費やすことがなくなります。
+ Spring Boot の自動化された機能により、開発者はコードをより迅速に開発し、より迅速に反復してビルド、テスト、デプロイを行うことができます。
+ 柔軟性が高く、豊富なライブラリを備えているため、多様な用途に対応できます。
+ Spring Cloud を使用することで、アプリケーションをマイクロサービスとして実行するための拡張機能を提供し、スケーラビリティと堅牢性を向上できます。

</details>

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  
+ [WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  

<details>

WSL (Microsoft Store アプリ版)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

Java JDK [※ Java JDK の導入と Hello World!](https://qiita.com/hiroxpepe/items/8650664e466906a57996)

```sh
$ java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
```

Maven [※ Maven の導入と Hello World!](https://qiita.com/hiroxpepe/items/40f7f199b9be7f9e3b5b)

```sh
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.17, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
```

</details>

※ この記事では基本的に Ubuntu のターミナルで操作を行います。

## "Hello World" を表示する手順

### プロジェクトフォルダの作成

※ ~/tmp/hello-spring-boot をプロジェクトフォルダとします。

```sh
$ cd ~
$ mkdir -p tmp/hello-spring-boot
$ cd ~/tmp/hello-spring-boot
```

### アプリケーションクラスの作成

```sh
$ mkdir -p src/main/java/com/example/springboot
$ vim src/main/java/com/example/springboot/Application.java
```

ファイルの内容

```java:Application.java
package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
```

<details>
<summary>説明を開きます。</summary>

このコードは、Spring Boot を使用して Web アプリケーションを作成するための基本的なクラスです。

具体的には、@SpringBootApplication アノテーションが付与された Application クラスを定義しています。 @SpringBootApplication アノテーションは、Spring Boot の自動設定を有効にするために必要です。これにより、Spring Boot はクラスパスに基づいて自動的に必要な設定を検出し、アプリケーションを自動構成します。  

そして、main メソッドはアプリケーションを起動するために必要なもので、SpringApplication.run() メソッドを呼び出して、Application クラスを渡します。このメソッドは、Spring Boot アプリケーションを起動し、必要な設定をロードします。そして、アプリケーションを実行します。  

つまり、このコードは Spring Boot アプリケーションを起動するための最小限のコードであり、アプリケーションの構成やルーティングのような詳細な設定は、別途追加する必要があります。  

</details>

### コントローラークラスの作成

```sh
$ mkdir -p src/main/java/com/example/springboot/controller
$ vim src/main/java/com/example/springboot/controller/HelloController.java
```

ファイルの内容

```java:HelloController.java
package com.example.springboot.controller;

import java.util.Map;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/data")
    public Map<String, String> getData() {
        Map<String, String> map = Map.of("message", "Hello World!");
        return map;
    }
}
```

<details>
<summary>説明を開きます。</summary>

このコードは、Spring Boot アプリケーションにおける REST API エンドポイントを定義するためのクラスです。  

具体的には、@RestController アノテーションが付与された HelloController クラスを定義しています。 @RestController アノテーションは、クラスが RESTful なエンドポイントを定義することを示します。  

@RequestMapping アノテーションは、HTTP リクエストに応じてこのエンドポイントに到達するための URL パスを定義します。この場合、リクエストパスは /apiにマッピングされます。  

そして、@GetMapping アノテーションが付与された getData メソッドは、HTTP GET リクエストを受け取り、Map オブジェクトを返すように定義されています。この場合、Map にはキーと値が1つだけ含まれており、"message" というキーに "Hello World!" という値が割り当てられています。  

したがって、このコードを実行すると、/api/data への GET リクエストが送信され、"Hello World!" という JSON レスポンスが返されます。  

</details>

### pom.xml の作成

```sh
$ vim pom.xml
```

ファイルの内容  

```xml:pom.xml
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>hello-spring-boot</artifactId>
    <version>1.0</version>
    <name>hello-spring-boot</name>

    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
```

### ディレクトリ・ファイル構成

```sh
$ tree
.
├── pom.xml
└── src
    └── main
        └── java
            └── com
                └── example
                    └── springboot
                        ├── Application.java
                        └── controller
                            └── HelloController.java
```

### Spring Boot アプリを実行

アプリビルド  
※ target/app.jar が作成されます。  

```sh
$ mvn clean install
```

アプリ起動 (Ctrl + C で停止します)

```sh
$ mvn spring-boot:run
```

WEBブラウザで確認

```sh
http://localhost:8080/api/data
```

WEBブラウザに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。  

別ターミナルのコマンドで確認

```sh
$ curl -v http://localhost:8080/api/data
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api/data HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Sat, 25 Feb 2023 05:13:10 GMT
<
* Connection #0 to host localhost left intact
{"message":"Hello World!"}
```

ターミナルに {"message":"Hello World!"} と表示され、JSON データを取得することが出来ました。  

## まとめ

+ Ubuntu のシンプルな構成の Java 開発環境で、Spring Boot WEBサービスを実行することが出来ました。
+ また、Spring Boot を使用しない素の [Spring MVC REST WEBサービスの Hello World!](https://qiita.com/hiroxpepe/items/6cf3842014b2a6ed8686)と比較すると、少ない記述で同じ動作を実装することが出来ました。