【Spring Boot】Controllerの基礎(REST API)
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-urlencoded
とapplication/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) {
//...
}