Spring MVC [API계층]

손정훈·2023년 2월 13일
0

Spring MVC

목록 보기
1/5

Spring MVC 흐름

Client가 요청 데이터 전송 → Controller가 요청 데이터 수신 → 비즈니스 로직 처리 → Model 데이터 생성 → Controller에게 Model 데이터 전달 → Controller가 View에게 Model 데이터 전달 → View가 응답 데이터 생성
  • @RestController : 해당 클래스가 REST API의 리소스를 처리하기 위한 API 엔드포인트로 동작함을 정의

RequestMapping 애너테이션

클라이언트의 요청과 Controller의 핸들러 메서드를 매핑하기 위해서 사용하는 애너테이션

일반적으로 공통 URI는 클래스 레벨에 정의하고, 핸들러 메서드별로 달라지는 URI는 각각의 핸들러 메서드에 정의

Method설명
@GetMappingHTTP Get Method에 해당하는 단축 표현으로 서버의 리소스를 조회할 때 사용
@PostMappingHTTP Post Method에 해당하는 단축 표현으로 서버에 리소스를 등록(저장)할 때 사용
@PutMappingHTTP Put Method에 해당하는 단축 표현으로 서버의 리소스를 수정할 때 사용. 리소스의 모든 정보를 수정할 때 사용
@PatchMappingHTTP Put Method에 해당하는 단축 표현으로 서버의 리소스를 수정할 때 사용. 리소스의 일부 정보만 수정할 때 사용
@DeleteMappingHTTP Delete Method에 해당하는 단축 표현으로 서버의 리소스를 삭제할 때 사용

Controller 핸들러 메서드

Method설명
@RequestParam쿼리 파라미터, form-data 등의 Servlet request Parameter를 바인딩 해야 할 경우 사용
@RequestHeaderrequest header를 바인딩해서 header의 key/value에 접근할 수 있음
@RequestBodyrequest body를 읽어서 지정한 Java 객체로 deserialization
@RequestPart'multipart/form-data' 형식의 request 데이터를 part 별로 바인딩할 수 있도록 해줌
@PathVariable@RequestMapping 에 패턴 형식으로 정의된 URL의 변수에 바인딩할 수 있도록 해줌
@MatrixVariableURL 경로 세그먼트 부분에 key/value 쌍으로 된 데이터에 바인딩할 수 있도록 해줌
HttpEntityrequest header와 body에 접근할 수 있는 컨테이너 객체를 사용할 수 있음


@RestController
@RequestMapping("/v1/coffees")
public class CoffeeController {
    private final Map<Long, Map<String, Object>> coffees = new HashMap<>();

    @PostConstruct
    public void init() {
        Map<String, Object> coffee1 = new HashMap<>();
        long coffeeId = 1L;
        coffee1.put("coffeeId", coffeeId);
        coffee1.put("korName", "바닐라 라떼");
        coffee1.put("engName", "Vanilla Latte");
        coffee1.put("price", 4500);

        coffees.put(coffeeId, coffee1);
    }

    // 1. 커피 정보 수정을 위한 핸들러 메서드 구현
    @PatchMapping("/{coffee-id}")
    public ResponseEntity patchCoffee(@PathVariable("coffee-id") long coffeeId) {
        coffees.get(coffeeId).put("korName", "바닐라 빈 라떼");
        coffees.get(coffeeId).put("price", 5000);

        return new ResponseEntity<>(coffees.get(coffeeId), HttpStatus.OK);
    }
    // 2. 커피 정보 삭제를 위한 핸들러 서드 구현
    @DeleteMapping("/{coffee-id}")
    public ResponseEntity deleteCoffee(@PathVariable("coffee-id") long coffeeId) {
        coffees.remove(coffeeId);

        return new ResponseEntity<>(coffees.get(coffeeId), HttpStatus.NO_CONTENT);
    }
}

DTO (Data Transfer Object)

바로 요청 데이터를 하나의 객체로 전달 받는 역할

데이터를 전달하기 위해 사용하는 객체

DTO가 필요한 이유

기존코드

@RestController
@RequestMapping("/v1/members")
public class MemberController {
    @PostMapping
    public ResponseEntity postMember(@RequestParam("email") String email,
                                     @RequestParam("name") String name,
                                     @RequestParam("phone") String phone) {
        Map<String, String> map = new HashMap<>();
        map.put("email", email);
        map.put("name", name);
        map.put("phone", phone);
        return new ResponseEntity<Map>(map, HttpStatus.CREATED);
    }
		...
		...
}

회원의 정보를 저장하기 위해 @RequestParam 애너테이션의 개수가 늘어남에 따라 코드가 복잡해짐

▶ 이를 해결하기 위해서 DTO클래스 사용

@RestController
@RequestMapping("/v1/members")
public class MemberController {
  @PostMapping
  public ResponseEntity postMember(@Valid MemberDto memberDto) {
      return new ResponseEntity<MemberDto>(memberDto, HttpStatus.CREATED);
  }
		...
		...
}

DTO 클래스

public class MemberDto {
    @Email
    private String email;
    private String name;
    private String phone;
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

0개의 댓글