Spring boot を のチュートリアルをやってみたpart1

# はじめに
記事を書いてる本人もJava歴１年未満＆Spring framework歴数ヶ月の人間です
(フレームワークもろくに触ったことないです)

フレームワークを触るにあたって、チュートリアルのようなものがあるので、それを実践してわかったことや用語のまとめなどをしていきます。(忘備録のようなものだとおもってください)

# チュートリアルをやってみる
以下のリンクより、チュートリアルを実践できます
https://spring.io/guides/

最初の「RESTful Webサービスの構築」というのからまず取り組みます
(RESTfulなサービスとは？という方はこちらの記事をぜひ御覧ください
→https://qiita.com/o_q/items/0bb7963f87308f4ca4bc)

# 目標
「http://localhost:8080/greeting 」 にアクセスしたとき、HTTP GETが動き、以下のJSON形式の返答を受け取る
```
{"id":1,"content":"Hello, World!"}
```
URLの後ろに「?name=User」 を追加した「http://localhost:8080/greeting?name=User 」 にアクセスしたときの返答が以下のようになる
```
{"id":1,"content":"Hello, User!"}
```

このように挨拶してくれるサービスを作る

# 最初にやったこと
- Java17以上 のインストール
- Gradle 7.5以上 のインストール
- VSCodeにSpring bootのプラグインをインストール

全部入ってなかったので、上から順番にやった
```
brew install openjdk@17
```
```
brew install gradle
```
![スクリーンショット 2024-01-02 17.06.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/32f7ae09-2ee6-c37e-d15a-d6bc27cffcd3.png)
![スクリーンショット 2024-01-02 17.06.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/787df0f2-ff8f-27f4-5a72-ea334cbd582a.png)

# 完成品のダウンロード
すでに完成しているzipフォルダをダウンロード解凍 or gitでクローンする(自分は後者)
```
git clone https://github.com/spring-guides/gs-rest-service.git
```
zipダウンロードのリンクは以下
https://github.com/spring-guides/gs-rest-service/archive/main.zip

# 初期状態のものをダウンロード
以下にアクセス
https://start.spring.io/

![スクリーンショット 2024-01-02 17.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/06921c32-aa1c-0705-7a83-70e07f06daca.png)

ここで、
Project 「Gradle - Groovy」
Language 「Java」
Spring boot 「3.1.7」
Project Metadata はいじらない
Packaging 「Jar」
Java 「17」
を選択
その後、右側の画面にある「ADD DEPENDENCES...」をクリックして「Spring Web」を選択
![スクリーンショット 2024-01-02 17.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/87e84e10-ca62-27f4-8660-5e1d5244fe63.png)

最終的にこのような画面になっていたらok
下にある「GENERATE」をクリックしてダウンロードをする
![スクリーンショット 2024-01-02 17.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/40159df3-8f4b-9dd8-947b-77803483695b.png)

ダウンロードした完成品と初期状態のものは同じディレクトリ内に入れておく
初期状態のものはzipになっているので解凍する

(GradleとMavenの違いって何?とかは別記事で→coming soon...)

# VSCodeで開いてみる

色々入ってるのがわかる
![スクリーンショット 2024-01-02 17.31.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/6b3166c1-3aba-b97a-0f41-b7630c020763.png)

### GET したときのレスポンス部分を作る

src/main/java/com/example/demo/に
Greeting.java
というファイルを作って、以下を貼り付ける
```
package com.example.restservice;

public record Greeting(long id, String content) { }
```

![スクリーンショット 2024-01-02 17.30.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/e2060cc1-1a8f-f6e8-e44b-a61ab6a7a21d.png)

ここでのidは一意に識別するための番号、contentは文字「Hello World!」などを表現するために用意した引数
(Greetingとは「挨拶する」の意)

※JacksonJSONというJavaオブジェクトとJSONを相互変換できるのライブラリを使っているので、この書き方ができる。Jacksonを使用するためには、以下のコードを「build.gradle」というファイルに書き込む必要がある
```
dependencies {
    compile 'com.fasterxml.jackson.core:jackson-databind:2.3.4'
}
```
今回は以下の「starter-web」の中にすでに入っている様子
```
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

### コントローラーを作る
HTTP リクエストを処理するコントローラーを作成する
src/main/java/com/example/demo/ に
GreetingController.java
を作成
以下のコードを貼り付け
```
package com.example.restservice;

import java.util.concurrent.atomic.AtomicLong;

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

@RestController
public class GreetingController {

	private static final String template = "Hello, %s!";
	private final AtomicLong counter = new AtomicLong();

	@GetMapping("/greeting")
	public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}
}
```
![スクリーンショット 2024-01-02 18.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/17af7dcd-7bc0-bc8a-e8f8-a127b7a9fa1b.png)

HTTPメソッドは「@RestController」 という ※アノテーション によって識別される
ここで注目すべきは「@GetMapping」の部分
```
@GetMapping("/greeting")
	public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}
```
「@GetMapping("/greeting")」と言う部分の意味は、**このURLに対してGETリクエストを要求したときに**、下の「public Greeting greeting(...)...」を実行するよ〜って意味です！
ではGETリクエストが要求されたときにどういった処理をするのか詳しく見て見ましょう

※アノテーションとは、「注釈、注意」を意味する言葉で、アノテーションによって色々役に立つことがあります。
「ここはこんな役割がありますよ、こういう処理しますよ」という「コメント」のような役割で書かれたりします。他にも機能はありますが、詳しい解説は別記事で→coming soon...

#### RequestParamについて
「@RequestParam」というアノテーションがありますね。これは**GETリクエストと一緒に、valueで指定されたクエリパラメータが付属して飛んできたときに別の処理ができるようにするためのもの**です。
ここでいう「クエリパラメータ」というのが、URIの後ろにくっつく「?name=User」のような部分のことを指します。
そして、この「?」の後ろにくっつく「name」とかが、「value」で指定されている部分になるわけです
今回であれば、「@RequestParam(value = "name", ...)」と書かれているので、「**?name = ◯◯」というGETリクエストが飛んできたときに処理を変える**という動的で柔軟な動きを見せることができます。(〇〇は文字列です)
また、「defaultvalue = "world"」というのは、クエリパラメータが指定されてないときに、デフォルトで「?name = world」になるという意味です
今回の目標を再度確認していただければ分かるように、「http://localhost:8080/greeting 」にアクセスしたときと、「http://localhost:8080/greeting?name=User 」にアクセスしたときでは、違うレスポンスになることを期待しています。

#### String name
String nameは引数です。実行結果によって返ってくる値をString型の引数nameに入れます

#### greetingメソッドの中身
```
return new Greeting(counter.incrementAndGet(), String.format(template, name));
```
new Greetingの中身に注目です
##### counter.incrementAndget() の部分
counterというのが、@GetMappingの前に定義したAtomicLong型の変数です
```
private final AtomicLong counter = new AtomicLong();
```
incrementAndGet() というメソッドは、AtomicIntegerクラスのメソッド一つで、AtomicIntegerの現在の値を1増やし、その新しい値を返します。AtomicLongはLong型のAtomicIntegerという意味です。

(※Atomicというのは「不可分」と訳されることが多い、「他のスレッドで同時にメソッドを呼び出しても正確な値が得られる」という値の操作に非常に慎重なメソッドや引数であることを示しています。)

##### String.format(template, name)の部分
String.formatは、Javaで文字列をフォーマットするためのメソッドです。
```
String template = String.format("書式指定文字列", 引数1, 引数2, ...);
```
今回引数templateで、%sという書式指定子を使用しています。
```
private static final String template = "Hello, %s!";
```
**この書式指定子%sに、引数nameを入れる**という処理をしているのが、「String.format(template, name)」の部分になります　

### コントローラーの処理のまとめ
「GreetingController.java」の処理の概要は、GETリクエストが特定のURIに対して行われたときに、クエリパラメータによって「Hello World!」や「Hello User」の文字列を返す

### アプリケーションクラスの作成
メインとなって動くアプリケーションクラスの作成をします
src/main/java/com/example/demoの下に
DemoApplication.java
を作成
以下のコードを作成
```
package com.example.demo;

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

@SpringBootApplication
public class DemoApplication {

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

}
```
mainクラスがあります
クラス内のメソッド「SpringApplication.run(DemoApplication.class, args);」はどういった処理なのか見てみましょう

#### SpringApplication.run
指定されたクラス（DemoApplication.class）とコマンドライン引数（args）を使用してSpringアプリケーションを起動します。
@SpringBootApplication は複数のアノテーションを追加する便利なアノテーションです。詳しく今回使用したアノテーションについては別記事でまとめます→coming soon...
大雑把に言うと、クラスパスの設定とか、プロパティの設定とかをSpring bootに指示するアノテーションがあるのですが、それらをまとめてやってくれます

## 完成!!!!
これでガイドに書いてあるコードの作成は終わったので、動かします。
今回Gradleを使用しているので、以下のコードでビルドしたあと、走らせます。
```
./gradlew build
```
```
./gradlew bootRun
```
![スクリーンショット 2024-01-03 4.47.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634272/4f76dbdb-57ae-880d-99d1-8b26eabb6bd0.png)

こんな感じで動くはずです！
そしたら、目標であるURLを２つ踏んでみましょう、それぞれ違った結果が得られるはずです！
http://localhost:8080/greeting
http://localhost:8080/greeting?name=User

# まとめ
これでRESTfulなWebサービスの構築は完成した模様です。
@GetMapping のアノテーションがついていた部分は@PostMapping のように、POSTに変えられたりするので、少しいじってRESTfulを感じてみるのもいいかもしれません。(今後のチュートリアルで出てくるかもしれないですが...)

今後もチュートリアル進み次第、書いていく所存ですので、もしSpring Frameworkを使い始めて、チュートリアルのガイドを読んで詰まってしまったという人はぜひご参考までに。