docker-compose 下で Java + Spring Boot + 簡単なWeb API を作ってみる
TL;DR
- 下記記事に書いてあるようなことをします
 - Spring Boot RestControllerメモ(Hishidama's Spring Boot RestController Memo) | ひしだま's ホームページ
 - 導入の部分は以下とほぼ同じです
- docker-compose 下で Java + Spring Boot 環境を作ってみる | 北山淳也 | zenn
 
 
docker-compose.yml を用意する
cd your_project
mkdir server
touch docker-compose.yml
docker-compose.yml
version: '3.6'
services:
  app:
    image: openjdk:15
    ports:
      - 8080:8080
    tty: true
    volumes:
      - ./server:/srv:cached
    working_dir: /srv
- OpenJDK | DockerHub
 - JDK Project Releases | OpenJDK
- 指定できるバージョン情報はここ
 - http://openjdk.java.net/projects/jdk/
 
 
Gradleプロジェクト作成
今回も Spring Initializr というサイトで作ってしまいます。
- Spring Initializr
 
前回の記事との違いは特にないです。
入力が終わったら GENERATE してダウンロードします。
ダウンロードしたら展開したものを
your_project/server 配下に配置します。
server/src/main/java/com/example/api/ApiApplication.java はダウンロードしてきたままでOK.
package com.example.api;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ApiApplication {
	public static void main(String[] args) {
		SpringApplication.run(ApiApplication.class, args);
	}
}
簡単な GETリクエストを受けつけてみる
mkdir server/src/main/java/com/example/api/controllers
touch server/src/main/java/com/example/api/controllers/TestController.java
こんな感じのファイルを用意する
package com.example.api.controllers;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @RequestMapping(path = "/test", method = RequestMethod.GET)
    public String test() {
      return "ok from test.";
    }
}
用意したら、Docker コンテナを起動してGradleビルド, アプリケーション起動
docker-compose up -d
docker-compose exec app bash
bash-4.4# pwd
/srv
bash-4.4# sh gradlew build
bash-4.4# java -jar build/libs/api-0.0.1-SNAPSHOT.jar
起動したら http://localhost:8080/test へcURLでリクエストを投げてみます。
$ curl http://localhost:8080/test -X GET
ok from test.
いい感じですね。
参考にした記事には org.springframework.boot:spring-boot-starter-data-rest が必要との記述がありましたが、単純な RestController を作る分にはこのパッケージは不要です。
(RestController を使っていますが RESTfull なAPIは今回は作ってないです)
Spring Data REST は Entity と Repository を用意するだけで
RESTful な Endpoint が全部生える便利なパッケージですね。
- RestController を作るのに参考にしたサイト
- Spring Boot RestControllerメモ(Hishidama's Spring Boot RestController Memo) | ひしだま's ホームページ
 
 - Spring Data REST についてはこの辺参照
- Spring Data RESTでMySQLにアクセス | Qiita
 - Spring Data RESTを利用したAPIの設計と、作り直しまでの道のり | Rakuten.Inc | SlideShare
 
 - @RestController と @Controller の違い
- Difference between @RestController and @Controller Annotation in Spring MVC and RESTをテキトーに訳した | kagamihogeの日記
 
 
JSON をレスポンスしてみる
POJO(Plain Old Java Object) をreturnしてやるとJSONシリアライズしてレスポンスできる。
package com.example.api.controllers;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @RequestMapping(path = "/test", method = RequestMethod.GET)
    public String test() {
      return "ok from test.";
    }
    @RequestMapping(path = "/test/json", method = RequestMethod.GET)
    public Example testJson() {
      var examplePOJO = new Example();
      examplePOJO.value1 = "foo";
      examplePOJO.value2 = "bar";
      return examplePOJO;
    }
    public class Example {
  		public String value1;
	  	public String value2;
	  }
}
コンパイルしてサーバー起動し直し
bash-4.4# sh gradlew build
bash-4.4# java -jar build/libs/api-0.0.1-SNAPSHOT.jar
起動したら http://localhost:8080/test/json へcURLでリクエストを投げてみます。
$ curl http://localhost:8080/test/json -X GET
{"value1":"foo","value2":"bar"}
いい感じですね。
内部では Jackson がよしなにシリアライズしてくれてるみたいです。
簡単な POSTリクエストを受けつけてみる
package com.example.api.controllers;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @RequestMapping(path = "/test", method = RequestMethod.GET)
    public String test() {
      return "ok from test.";
    }
    @RequestMapping(path = "/test/json", method = RequestMethod.GET)
    public Example testJson() {
      var examplePOJO = new Example();
      examplePOJO.value1 = "foo";
      examplePOJO.value2 = "bar";
      return examplePOJO;
    }
    @RequestMapping(path = "/test/post", method = RequestMethod.POST)
    public Example testPost(@RequestBody Example requestPOJO) {
      requestPOJO.value1 = requestPOJO.value1 + ":AddServer";
      requestPOJO.value2 = requestPOJO.value2 + ":AddServer";
      return requestPOJO;
    }
    // static class で宣言しないと @RequestBody で受け取れない……?
    public static class Example {
  		public String value1;
	  	public String value2;
	  }
}
import org.springframework.web.bind.annotation.RequestBody; を追加していますが
ワイルドカード指定で
import org.springframework.web.bind.annotation.*; でもいいかもしれませんね。
- REST コントローラーの作成 - @RestController | 独習Spring
 
コンパイルしてサーバー起動し直し
bash-4.4# sh gradlew build
bash-4.4# java -jar build/libs/api-0.0.1-SNAPSHOT.jar
起動したら http://localhost:8080/test/post へcURLでリクエストを投げてみます。
$ curl http://localhost:8080/test/post -X POST -H 'Content-Type: application/json' -d '{"value1":"hoge","value2":"fuga"}'
{"value1":"hoge:AddServer","value2":"fuga:AddServer"}
いい感じですね!
今回のリポジトリはこちら
Discussion
記事拝見させていただきました。
最近SpringBootの勉強をし始めたばかりだったので、大変参考になりました。
ありがとうございました。
1点もしお分かりであれば教えていただきたいことがあるのですが、よろしいでしょうか?
とコード中に記載されており、試したところ確かにstatic修飾子をつけないとエラーになりました。
調べたところ、これといった情報を得ることができませんでした。
staticをつけるつけないでどのように変わるか既に解決済みでしたらお教えいただけませんでしょうか?