[Spring MVC] API계층

·2022년 10월 25일
0

Spring

목록 보기
12/24
post-thumbnail
post-custom-banner

API 계층

: Controller에 해당하며, 클라이언트의 요청을 직접적으로 전달 받는 계층

엔트리포인트(Entrypoint) 클래스 작성

Spring Boot 기반의 애플리케이션이 정상적으로 실행되지 위해서는 main() 메서드가 포함된 애플리케이션의 시작점인 엔트리포인트 클래스를 작성해야 한다.

  • Spring Initializr에 의해 엔트리포인트 클래스는 자동 생성된다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EntrypointClass {

	public static void main(String[] args) {
		SpringApplication.run(EntrypointClass.class, args);
	}
}

☝️@SpringBootApplication

  1. 자동 구성을 활성화한다.
  2. 애플리케이션 패키지 내에 @Component가 붙은 클래스를 Scan한 후, Spring Bean에 등록해준다.
  3. @Configuration이 붙은 클래스를 자동으로 찾아, 추가적으로 Spring Bean 등록해준다.

💡주의할 점
엔트리포인트 클래스는 최상위 패키지에 존재해야 한다. 또한, 엔트리포인트 클래스로 인해 실행되는 모든 클래스는 엔트리포인트 클래스의 동일, 하위 패키지에 위치해야 한다.

가능 😊👌

불가능 🤬👎

☝️SpringApplication.run(ntrypointClass.class, args);

  • Spring 애플리케이션을 부트스트랩하고 실행하는 역할을 한다.
  • ☝️ 부트스트랩(BootStrap)?
    : 애플리케이션이 실행되기 전에 여러가지 설정 작업을 수행하여 실행 가능한 애플리케이션으로 만드는 단계

Controller 설계

핸들러 메서드(Handler Method)

  • Controller 클래스에서 클라이언트의 요청을 처리하는 역할을 한다.

@RestController

  • 클래스 레벨에 추가하는 애너테이션
  • @Controller와 같은 역할을 하며, REST API의 리소스를 처리하기 위한 API 엔트포인트로 동작함을 정의한다.
  • @RestController = @Controller + @ResponseBody
  • 해당 애너테이션이 추가된 클래스는 Spring Bean에 등록된다.

@RequestMapping

  • 클래스 레벨에 추가하는 에너테이션(메서드 레벨에도 사용이 가능하다)
  • 클라이언트의 요청과 핸들러 메서드(Handler Method)를 매핑해주는 역할을 한다.
  • 클래스 전체에 사용되는 공통 URL을 설정할 수 있다.
@RequestMapping("공통 URL")

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

@RequestMapping의 단축 표현

HTTP Method에 해당하는 단축 표현을 주로 사용하며 해당 애너테이션들은 메서드 레벨에 사용하는 것을 권장한다.

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @PatchMapping
  • @DeleteMapping

💡핸들러 메서드에 URI를 추가하는 방법!

@PatchMapping("/{member-id}")
public ResponseEntity patchMember(@PathVariable("member-id") long memberId){
...
}

@PatchMapping("/{member-id}")@PathVariable("member-id") long memberId 의 member-id는 같은 값을 말하며 해당 값은 memberId 파라미터로 받는다.

DTO(Data Transfer Object)

DTO란?

  • 데이터의 형식을 변환해주는 역할을 한다.
  • 클라이언트가 보내는 데이터의 유효성 검증을 할 수 있다.
  • DTO의 목적 : HTTP 요청의 수를 줄이기 위해 (비용절감)
  • DTO의 단점 : Controller가 늘어남에 따라 DTO클래스도 배로 증가한다.

💡JSON의 직렬화와 역직렬화
직렬화 : JAVA 객체 -> JSON 형식
역직렬화 : JSON 형식 -> JAVA 객체

DTO class

: Request Body를 하나의 객체로 전달 받는다.

  • 멤버변수와 그에 따른 Getter를 필수적으로 가진다.(setter는 개발자의 선택에 따른다.)

💡getter/setter 애너테이션
해당 클래스에 @Getter/@Setter 애너테이션을 추가하면 자동으로 getter/setter 메서드가 추가된다.

@RequestBody와 @ResponseBody

RequestBody와 ResponseBody를 각각에 맞는 DTO클래스와 매핑시켜 직렬화, 역직렬화 시켜야 한다. 이때 사용하는 애터네이션이 @RequestBody@ResponseBody이다.

@RequestBody

: JSON형식의 RequestBody를 DTO클래스의 객체로 변환시켜주는 애너테이션
Controller클래스에서 해당 메서드의 파라미터에 추가한다.

@PostMapping
    public ResponseEntity postMember(@RequestBody MemberPostDto memberDto) { ... }

@ResponseBody

: DTO 클래스의 객체를 Json 형식의 ResponseBody로 변환시켜주는 에너테이션

💡 핸들러 메서드의 리턴 타입이 RespontEntity일 경우, 내부에서 HttpMessageConverter가 동작해 자동으로 Json형식으로 변환 시켜준다. -> @ResponseBody 생략 가능

유효성 검사

: 클라이언트로부터 전달 받는 데이터들의 누락 및 오류 발생을 방지하기 위해서 진행하며, 프론트엔드에서 일차적으로 유효성 검증을 진행하지만, 이는 사용자의 편의성을 위해 진행하는 것이나 다름없어 서버에서도 한번 더 유효성 검증을 진행해야 한다.

유효성 검증 하는 방법

  1. DTO 클래스 멤버 변수에 에너태이션을 추가한다.
    @NotBlank
    @Email
    private String email;

    @NotBlank(message = "이름은 공백이 아니어야 합니다.")
    private String name;

    @Pattern(regexp = "^010-\\d{3,4}-\\d{4}$",
            message = "휴대폰 번호는 010으로 시작하는 11자리 숫자와 '-'로 구성되어야 합니다.")
    private String phone;
  • @NotBlank : 공백을 허용하지 않는다. (null값, "", " ")
  • @Email : 유효한 이메일 주소인지 검증
  • @Pattern : regexp(정규표현식)과 일치하는 지 검증
  1. 유효성 검증을 적용하기 위해 해당 핸들러 메서드에 @Valid 애너테이션을 추가
@PostMapping
    public ResponseEntity postMember(@Valid @RequestBody MemberPostDto memberDto) { ... }
  1. Cotroller 클래스에서의 유효성 검증
    : URI path가 있는 경우, 해당 값이 0 이상의 정수여야 한다.
@Validated
public class MemberController {

@PatchMapping("/{member-id}")
    public ResponseEntity patchMember(@PathVariable("member-id") @Positive long memberId, @Valid @RequestBody MemberPatchDto memberPatchDto) {...}

}
  • @Min(), @Max()
  • @Positive : 0 초과의 정수만 들어올 수 있다.
profile
🧑‍💻백엔드 개발자, 조금씩 꾸준하게
post-custom-banner

0개의 댓글