spring.svg

【Spring Boot】Controllerの基礎(REST API)

SpringBoot

Controller クラスの作成

REST API 用の Controller クラスには、@RestControllerというアノテーションを付与します。

@RestController
public class SampleController {
  //...
}

REST API ではなく、テンプレートエンジンなどを使用する場合は@Controllerを付与します。

HTTP メソッド

Spring Boot では、HTTP メソッドに対応するアノテーションが用意されています。

HTTP メソッドアノテーション
GET@GetMapping
POST@PostMapping
PUT@PutMapping
DELETE@DeleteMapping

メソッドに付与することで、そのメソッドの処理は HTTP メソッドに対応する処理となります。

@RestController
public class SampleController {
  @GetMapping
  public List<SampleData> findAll() {
    //...
  }

  @PostMapping
  public void create() {
    //...
  }
}

パスの指定

パスの指定は、上記の HTTP メソッドに対するアノテーションの引数として指定します。

//GET http://localhost:8080/sample-data
@GetMapping("sample-data")
public List<SampleData> findAll() {
  //....
}

//POST http://localhost:8080/sample-data
@PostMapping("sample-data")
public void create() {
  //...
}

Controller で共通のパスを指定するには、@RequestMappingをクラスに付与します。

@RestController
@RequestMapping
public class SampleController {
  //GET http://localhost:8080/sample-data
  @GetMapping
  public List<SampleData> findAll() {
    //...
  }

  //POST http://localhost:8080/sample-data
  @PostMapping
  public void create() {

  }
}

レスポンス

レスポンスとしてどのようなデータを返したいかは、メソッドの戻り値で決まります。

シンプルなテキストとして返したい場合は、Stringを戻り値とします。

JSON 形式で返したい場合は、対応するクラスを作成して戻り値とします。 このとき、JSON のプロパティはクラスのゲッターを基に設定されます。

  • クラス
    public class SampleData {
      private String id;
      private String firstName;
      private String lastName;
      private int age;
    
      public SampleData(String id, String firstName, String lastName String age) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
      }
    
      public String getId() {
        return id;
      }
    
      public String getName() {
        return firstName + " " + lastName;
      }
    
      public int getAge() {
        return age;
      }
    }
  • Controller
    @GetMapping
    public SampleData getSampleData() {
      return new ("000001", "taro", "yamada", 20);
    }
  • レスポンス(JSON)
    {
      "id": "000001",
      "name": "taro yamada",
      "age": 20
    }

リクエストパラメーターについて

リクエストにパラメーターを含める方法としては、以下の 3 つがあります。

クエリ

GET /sample-data?id=000001 HTTP/1.1

URL の末尾にパラメーターを含める方法で、主に GET で使用します。

?以降にパラメーター名=値として定義します。複数ある場合は&で繋げます。

リクエストボディ

POST /sample-data HTTP/1.1
Content-Type: application/x-www-form-urlencoded

id=000001&firstName=taro&lastName=yamada&age=20
POST /sample-data HTTP/1.1
Content-Type: application/json

{
  "id": "000001",
  "firstName": "taro",
  "lastName": "yamada",
  "age": 20
}

リクエストボディにパラメーターを設定する方法で、GET 以外で使用します。

パラメーターのフォーマット(Content-Type)には、application/x-www-form-urlencodedapplication/jsonが使用されます。

パス

GET /sample-data/000001 HTTP/1.1

パスの一部をパラメーターとする方法で、GET と DELETE で使用します。

リクエストパラメーターの参照

@RequestParam

クエリパラメーターや、application/x-www-form-urlencodedとして送られる場合は、@RequestParamを使用します。

メソッドの引数にパラメーター名と同名の変数を定義し、@RequestParamを付与します。

@GetMapping
public SampleData findById(@RequestParam String id) {
  //...
}

@PostMapping
public void create(@RequestParam String id, @RequestParam String firstName,
    @RequestParam String lastName, @RequestParam int age) {
  //...
}

パラメーター名と変数名が異なる場合は、@RequestParam(name = "id") String fooIdのようにアノテーションの引数で指定します。

これらのパラメーターは必須となるため、指定されていない(null の)場合はMissingServletRequestParameterExceptionがスローされます。 必須でないパラメーターには、@RequestParam(required = false)として付与します。

また変数の型に変換できないパラメーターが渡された場合は、MethodArgumentTypeMismatchExceptionがスローされます。

DTO(Data Transfer Object)

@RequestParamによる指定方法では、1 つ 1 つパラメーターを定義しないといけないため、手間かつ見にくいものになってしまします。

これを解決するために、パラメーター名と同じ名前のフィールドにもつクラス(DTO)を作成します。 このときデフォルトコンストラクター(引数なしコンストラクター)とセッターを必ず作成してください。

public class SampleDataParam {
  String id;
  String firstName;
  String lastName;
  int age;

  public SampleDataParam(){
  }
}

@RequestParamの指定の代わりに、DTO を指定します。 これにより、パラメーターと同名のフィールドに値が設定されたインスタンスが生成されます。

@PostMapping
public void create(SampleDataParam param) {
  //...
}

int 型フィールドに"abcde"のような型変換できないパラメーターが渡された場合は、 HttpMessageNotReadableExceptionがスローされます。

以下で説明しますが、引数にアノテーションを指定していない場合は、application/x-www-form-urlencodedで送信されたパラメーターが紐づきます。

@ModelAttribute

DTO にクエリパラメーターを紐づける場合は、@ModelAttributeを付与します。

@GetMapping
public SampleData get(@ModelAttribute SampleDataParam param) {
  //...
}

@RequestBody

application/jsonとしてパラメーターを受け取る場合は、DTO に@RequestBodyを付与します。

@PostMapping
public void create(@RequestBody SampleDataParam param) {
  //...
}

@PathValiable

パスパラメーターを使用する場合は、まずパスのどの部分がパラメーターであるかを定義します。 定義は{パラメーター名}と指定します。

次にパラメーター用の変数を引数に定義し、@PathValiableを付与します。

@GetMapping("{id}")
public SampleData findById(@PathValidable String id) {
  //...
}