REST API is a promise to handle resources using only HTTP methods (GET / POST / PUT / DELETE) and URLs. In Spring Boot, it can be implemented very concisely with @RestController and various mapping annotations.
Learning Objectives
- Know the difference between
@RestControllerand@Controller - Know the meaning of
@GetMapping/@PostMapping/@PutMapping/@DeleteMapping - Receive input as
@PathVariableand@RequestParam - Receive JSON as an object with
@RequestBody - Reply with a status code of
ResponseEntity
Key concepts
1) @RestController
@RestController
@RequestMapping("/api/hello")
public class HelloController { ... }
Composition of @Controller + @ResponseBody. Serialize the return value as JSON and write it as is in the response body.
2) Mapping annotation
| annotation | HTTP Method |
|---|---|
@GetMapping |
GET |
@PostMapping |
POST |
@PutMapping |
PUT |
@DeleteMapping |
DELETE |
3) @PathVariable vs @RequestParam
@GetMapping("/users/{id}")
public User get(@PathVariable Long id) { ... } // /users/3
@GetMapping("/users")
public List<User> list(@RequestParam(defaultValue="0") int page) { ... }
// /users?page=2
4) @RequestBody
@PostMapping("/users")
public User create(@RequestBody UserCreateRequest req) { ... }
The JSON body is automatically converted to Java objects (using Jackson).
5) ResponseEntity
return ResponseEntity.status(HttpStatus.CREATED).body(user);
Used when specifying status code + header + body together.
See as example
Example 1 — HelloController.java : GET + @RequestParam
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(@RequestParam(defaultValue = "Spring") String name) {
return "Hello, " + name + "!";
}
}
curl-http/part/localhost-8083/hello-name-index → Hello, Jisoo!
Example 2 — GreetingController.java : @PathVariable + JSON
@RestController
@RequestMapping("/api/greetings")
public class GreetingController {
record Greeting(String message, int length) {}
@GetMapping("/{name}")
public Greeting greet(@PathVariable String name) {
String msg = "Hello, " + name + "!";
return new Greeting(msg, msg.length());
}
}
curl http://localhost:8083/api/greetings/Java → {"message":"Hello, Java!","length":12}
Example 3 — EchoController.java : POST + @RequestBody
@RestController
@RequestMapping("/api/echo")
public class EchoController {
record EchoRequest(String text, int repeat) {}
record EchoResponse(String result) {}
@PostMapping
public EchoResponse echo(@RequestBody EchoRequest req) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < req.repeat(); i++) sb.append(req.text());
return new EchoResponse(sb.toString());
}
}
curl -X POST http://localhost:8083/api/echo \
-H "Content-Type: application/json" \
-d '{"text":"hi","repeat":3}'
# {"result":"hihihi"}
Example 4 — StatusController.java : ResponseEntity
@RestController
public class StatusController {
@GetMapping("/teapot")
public ResponseEntity<String> teapot() {
return ResponseEntity.status(418).body("I'm a teapot");
}
@PostMapping("/items")
public ResponseEntity<String> create() {
return ResponseEntity.status(HttpStatus.CREATED).body("created");
}
}
run
cd 06_Spring_Boot/24_REST_Controller
mvn spring-boot:run
Common Mistakes
- Set to
@Controllerand JSON does not return → Use@RestController - Missing
@RequestParam→ If it is different from the method signature name, matching fails. - If
@RequestBodyis missing, the body is not mapped. - Omission of
("id")when the name of@PathVariableis different from the URL variable name. - Directly returning JSON incompatible types
Cleanup
- The combination of
@RestController+ mapping annotation is the basis of REST - Input is separated into
@RequestParam/@PathVariable/@RequestBody - If the status code is significant, it is
ResponseEntity
Try it yourself
cd 06_Spring_Boot/24_REST_Controller
mvn spring-boot:run
#another terminal
curl http://localhost:8083/hello
curl http://localhost:8083/api/greetings/Spring
curl -X POST http://localhost:8083/api/echo -H "Content-Type: application/json" -d '{"text":"hi","repeat":3}'