*모놀리식(Monolithic) 아키텍처: 단일 코드 베이스의 애플리케이션 (모든 것을 한곳에서 실행)
*마이크로서비스 아키텍처: 애플리케이션을 작은 서비스로 분할, 각 서비스가 독립적
REST API
REST (Representational State Transfer)
- 생존가능성(survivability), 회복탄력성(resilience)을 향상시킴
- 무상태 애플리케이션/서비스라고도 함
- 서비스마다 자체적으로 '현재 상태'를 가짐, 다른 서비스가 자기 서비스의 '현재 상태'를 저장하리라 기대하지 않기 때문
*무상태: 수신자(receiver)가 이전 요청(request)의 상태를 유지하지 않는 방식
- 안정성과 확장성에 유리하지만 요청을 재사용할 수 없으므로 반복 데이터로 네트워크 성능을 저하시킴
• REST API는 주로 아래의 HTTP 메서드를 기반으로 함
- 생성(POST), 읽기(GET), 업데이트(PUT, PATCH), 삭제(DELETE) + OPTIONS, HEAD
*의존성은 'RESTful을 포함한 웹을 만들고, 스프링 MVC를 사용한 애플리케이션'을 만드는 기능 등 여러 기능을 포함
RESTful API 만들기
3.4 GET으로 시작하기
• @RestController : @Controller와 @ResponseBody를 하나의 어노테이션으로 합쳐 쓴 것
• MVC의 여러 부분을 연결하는 데 @Controller 어노테이션이 도움됨
- @Controller (@Component의 별칭)
- @Controller가 붙은 클래스는 Model 객체를 받음
• @RequestMapping 에 있는 편리한 어노테이션
- @GetMapping
- @PostMapping
- @PutMapping
- @PatchMapping
- @DeleteMapping
@RestController
class RestApiDemoController{
private List<Coffee> coffees = new ArrayList<>();
public RestApiDemoController() {
coffees.addAll(Arrays.asList(
new Coffee("Cafe Cereza"),
new Coffee("Cafe Ganador"),
new Coffee("Cafe Lareno"),
new Coffee("Cafe Tres Pontas")
));
}
@RequestMapping(value = "/coffees", method = RequestMethod.GET)
Iterable<Coffee> getCoffees(){
return coffees;
}
}
@RestController
@RequestMapping("/")
class RestApiDemoController{
private List<Coffee> coffees = new ArrayList<>();
public RestApiDemoController() {
coffees.addAll(Arrays.asList(
new Coffee("Cafe Cereza"),
new Coffee("Cafe Ganador"),
new Coffee("Cafe Lareno"),
new Coffee("Cafe Tres Pontas")
));
}
@GetMapping("/coffees")
Iterable<Coffee> getCoffees(){
return coffees;
}
}
-> 위 아래 코드 동일하게 동작 .. 하는듯
3.4.2 POST로 생성하기 @PostMapping
Post는 리소스의 세부 정보(일반적으로 JSON 형식)를 제공. 해당 서비스에 POST 요청을 해서 지정된 URI에 리소스를 생성
3.4.3 PUT으로 업데이트하기 @PutMapping
일반적으로 PUT 요청은 파악된 URL를 통해 기존 리소스의 업데이트에 사용됨
✨PUT 메서드 응답 시 '상태코드'는 필수 -> ResponseEntity 반환
3.4.4 DELETE로 삭제하기 @DeleteMapping
HTTP의 DELETE의 요청은 리소스를 삭제함
(+) GET에는 특정 상태코드를 지정하지 않고, POST와 DELETE 메서드에는 '상태코드' 사용을 권장함
최종 코드
package com.thehecklers.sburrestdemo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class SburRestDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SburRestDemoApplication.class, args);
}
}
class Coffee {
private final String id;
private String name;
public Coffee(String id, String name) {
super();
this.id = id;
this.name = name;
}
public Coffee(String name) {
this(UUID.randomUUID().toString(), name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
}
@RestController
@RequestMapping("/coffees")
class RestApiDemoController {
private List<Coffee> coffees = new ArrayList<>();
public RestApiDemoController() {
coffees.addAll(Arrays.asList(
new Coffee("Cafe Cereza"),
new Coffee("Cafe Ganador"),
new Coffee("Cafe Lareno"),
new Coffee("Cafe Tres Pontas")
));
}
//@GetMapping
//Iterable<Coffee> getCoffees() {
// return coffees;
//}
@GetMapping
Optional<Coffee> getCoffeeById(@PathVariable String id){
for(Coffee c : coffees) {
if(c.getId().equals(id)) {
return Optional.of(c);
}
}
return Optional.empty();
}
@PostMapping
Coffee postCoffee(@RequestBody Coffee coffee) {
coffees.add(coffee);
return coffee;
}
@PutMapping("/{id}")
ResponseEntity<Coffee> putCoffee(@PathVariable String id, @RequestBody Coffee coffee) {
int coffeeIndex = -1;
for(Coffee c : coffees) {
if(c.getId().equals(id)) {
coffeeIndex = coffees.indexOf(c);
coffees.set(coffeeIndex, coffee);
}
}
return (coffeeIndex == -1) ?
new ResponseEntity<>(postCoffee(coffee), HttpStatus.CREATED) : //상태코드 반환 추가
new ResponseEntity<>(coffee, HttpStatus.OK);
}
@DeleteMapping("/{id}")
void deleteCoffee(@PathVariable String id) {
coffees.removeIf(c->c.getId().equals(id));
}
}
(+) GetMapping 어노테이션이 2개 있으면 오류나서 .. 하나 지움
API 사용해보기
HTTPie 사용
'Study > Spring Boot' 카테고리의 다른 글
6. 데이터 파고들기 (2) | 2023.12.14 |
---|---|
5. 애플리케이션 설정과 검사 (0) | 2023.09.17 |
4. 데이터베이스 액세스 (0) | 2023.09.10 |