SpringBoot + Swagger で REST APIを実装する

自分用メモ
　
【IDE】
　InteliJ IDEA CE


# Spring initializrでプロジェクトを作成
[Spring initializr](https://start.spring.io/)
　
【Project】
　Gradle を選択
　
【Language】
　Javaを選択
　
【SpringBoot】
　2.2.2を選択（SNAPSHOTがついていない最新のもの）
　
【Project Metadata】
　Group：適当に設定
　Artifact：適当に設定
　Options：Java8を選択、それ以外は任意で。（僕はJava8を選択しただけで、他は触ってません）
　
【Dependencies】
　Options：「MySQL」, 「Lombok」, 「Spring Data Redis」, 「Spring Web」, 「Spring Data JPA」
　
### inteliJでプロジェクトを開く
→「プロジェクトのインポート」　→　上記で作成したプロジェクトを選択してオープン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/25ec7895-bc1d-4950-689f-088afc86ff7f.png)
　
→「既存モデルからプロジェクトを作成する」にチェックして、Gradleを選択　→　完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/41edc305-07fd-89a3-ddab-039d88197cb3.png)


　
### inteliJでプロジェクトを開いたときに、以下のようなポップアップが表示される場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/1fedd6cd-a7dd-db86-3df7-0fd98b86d3d9.png)
　
→「preference」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/c49f6442-df30-3231-7e20-f27c8b7187ba.png)
　
→「ビルド・実行・デプロイ」　→　注釈プロセッサー　→　「注釈処理を使用可能にする」にチェック　→ 適用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/bf4ed8a1-a972-9d1d-a872-5119816ac400.png)
　
### 実行時、springboot finished with non-zero exit value 1で落ちる
少しハマりました。
MySQLの接続情報を記載しないといけないんですね・・・。
　

```docker/docker-compose.yml
version: '3'
services:
  db:
    image: mariadb:latest
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    environment:
      - MYSQL_ROOT_USER=root
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=ここは適当なDB名に変更してください
      - MYSQL_USER=user
      - MYSQL_PASSWORD=user
    volumes:
      - db_data:/var/lib/mysql
      - ./db_data:/docker-entrypoint-initdb.d
    ports:
      - '3333:3306'

volumes:
  db_data:
    driver: local
```
　

```src/main/java/resources/application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3333/docker-composeのMYSQL_DATABASEに指定した名称
    username: user
    password: user

  jpa:
    hibernate:
      ddl-auto: none
```
→僕はapplication.propertiesをapplication.ymlにリネームしてます。
　
dockerのDBコンテナを立ち上げ

```
docker-compose up -d
```
　
実行！！！

```
16:11:57: Executing task 'RedisApiSampleApplication.main()'...

> Task :compileJava UP-TO-DATE
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE

> Task :RedisApiSampleApplication.main()

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

2019-12-07 16:11:58.851  INFO 6017 --- [           main] r.r.RedisApiSampleApplication            : Starting RedisApiSampleApplication on ~ with PID 6017 (/Users/~/Desktop/workspace/redis-api-sample/build/classes/java/main started by ~ in /Users/~/Desktop/workspace/redis-api-sample)
2019-12-07 16:11:58.855  INFO 6017 --- [           main] r.r.RedisApiSampleApplication            : No active profile set, falling back to default profiles: default
2019-12-07 16:11:59.501  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2019-12-07 16:11:59.503  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2019-12-07 16:11:59.525  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12ms. Found 0 JPA repository interfaces.
2019-12-07 16:11:59.541  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2019-12-07 16:11:59.542  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2019-12-07 16:11:59.552  INFO 6017 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 1ms. Found 0 Redis repository interfaces.
2019-12-07 16:11:59.885  INFO 6017 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-12-07 16:12:00.298  INFO 6017 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-12-07 16:12:00.314  INFO 6017 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-12-07 16:12:00.315  INFO 6017 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.29]
2019-12-07 16:12:00.399  INFO 6017 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-12-07 16:12:00.399  INFO 6017 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1467 ms
2019-12-07 16:12:00.628  INFO 6017 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2019-12-07 16:12:00.688  INFO 6017 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate Core {5.4.9.Final}
2019-12-07 16:12:00.818  INFO 6017 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
2019-12-07 16:12:00.906  INFO 6017 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2019-12-07 16:12:01.097  INFO 6017 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2019-12-07 16:12:01.124  INFO 6017 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL55Dialect
2019-12-07 16:12:01.311  INFO 6017 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2019-12-07 16:12:01.317  INFO 6017 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2019-12-07 16:12:01.365  WARN 6017 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-12-07 16:12:01.517  INFO 6017 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-12-07 16:12:02.198  INFO 6017 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-12-07 16:12:02.201  INFO 6017 --- [           main] r.r.RedisApiSampleApplication            : Started RedisApiSampleApplication in 3.904 seconds (JVM running for 4.372)
```
無事、エラーが消えて実行できました。
　
# Spring Foxの導入
build.gradleのdependenciesに追記します。

```build.gradle
.
..
...
dependencies {
	implementation "io.springfox:springfox-swagger2:2.9.2"
	implementation 'io.springfox:springfox-swagger-ui:2.9.2'  // Swagger UIを利用するため
	...
	..
	.
}
...
..
.
```
　
追記後は、プロジェクトをリフレッシュします。
右端の「gradle」→再読み込みみたいなアイコンクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/729f9115-cfbd-1d26-10c4-ebfda924a663.png)
　
# swagger-foxを有効にする
### Swagger用のJavaConfigを用意していない場合
SpringApplication.run()があるクラスに@EnableSwagger2を付与する。

```src/main/java/example/Application.java
package redisapisample.redisapisample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;　←これを追記

@EnableSwagger2　←これを追記
@SpringBootApplication
public class RedisApiSampleApplication {

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

}
```

### Swagger用のJavaConfigを用意する場合
SwaggerConfig.java（ファイル名は任意でOK）を作成し、@Configurationと@EnableSwagger2を付与するだけ。

```src/main/java/example/config/SwaggerConfig.java
package redisapisample.redisapisample.config;

import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
}

```
　
### swagger-uiを表示する
アプリケーション実行後、[http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/9194205d-d0b0-1647-557e-71b2f8ee2085.png)
　
swagger-uiを表示することができました。
　
# APIの実装
### Controller
```src/main/java/example/RestExampleController.java
package redisapisample.redisapisample.Controller;

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

@RestController // Web Controllerとして利用するためのBean登録
@RequestMapping("/redis") // リクエストURL
public class RestExampleController {
    @GetMapping("/register")
    public String registerString() {
        return "ok";
    }
}
```
とりあえずこんだけ。
　
### Swagger-uiから実行してみる
swaggerに先ほど作成したcontrollerが追加されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/6865e8bb-2d84-16b5-71cb-f4b34d71b33e.png)
　
・try it outをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/51dff48a-c056-6037-de51-aea64c51b970.png)
　
・executeをクリックで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/c6f8a9eb-178a-2dc3-5d70-d31a391c79e0.png)
　
・200でちゃんと「ok」が返ってきている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/5ed1487a-b59b-1700-5587-3222f85ae815.png)

　
# 備考
### アプリケーションの実行
■bootRunで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/2d13fa56-dedc-bf9a-841f-15b3791de218.png)
　
■Application.javaを右クリックで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357470/71bded96-5936-ff89-2d7c-4a16898a84d3.png)