API 예외 처리

  • API는 단순 오류 페이지 반환보다 고려할 사항이 많다.

    • 모바일인지 웹인지

    • MSA끼리의 통신인지

    • 다른 회사에 기능을 제공하는 API인지

  • 오류 페이지는 화면만 보여주면 끝이지만 API는 각 오류 상황에 맞게 스펙을 정해야 한다.

@Slf4j
@RestController
public class ApiExceptionController {

    @GetMapping("/api/members/{id}")
    public MemberDto getMember(@PathVariable("id") String id) {
        if (id.equals("ex")) {
            throw new RuntimeException("잘못된 사용자");
        }

        return new MemberDto(id, "hello " + id);
    }

    @Data
    @AllArgsConstructor
    static class MemberDto {
        private String memberId;
        private String name;
    }
}
  • WebServerCustomizer

    • WAS에 예외가 전달되거나 response.sendError()가 호출되면 등록한 예외 페이지가 호출된다.

  • 예외가 발생하면 JSON으로 반환해야 한다.

  • 하지만 이 컨트롤러는 우리가 미리 만들었던 HTML 오류 페이지를 반환한다.

  • 웹 브라우저가 아닌 클라이언트라면 이걸 받아서 할 수 있는 게 없다.

@Slf4j
@Controller
public class ErrorPageController {

    ...

    @RequestMapping("/error-page/404")
    public String errorPage404(HttpServletRequest request, HttpServletResponse response) {
        log.info("errorPage 404");
        printErrorInfo(request);
        return "error-page/404";
    }

    @RequestMapping("/error-page/500")
    public String errorPage500(HttpServletRequest request, HttpServletResponse response) {
        log.info("errorPage 500");
        printErrorInfo(request);
        return "error-page/500";
    }
}
  • HTML 화면을 날리는 이유는 ErrorPageController에 정의된 메서드가 호출되기 때문이다.

  • produces를 정의해 클라이언트가 받고 싶어하는 미디어 타입에 따라 메서드를 호출하게 변경한다.

  • JSON으로 반환하기 위해 ResponseEntity를 사용한다.

    • 메시지 컨버터가 동작하면서 데이터를 JSON으로 변환한다.

produces = MediaType.APPLICATION_JSON_VALUE

  • 클라이언트가 요청하는 HTTP header의 Aceept값이 application/json인 경우 해당 메서드를 호출한다.

  • Accept 헤더를 지정한 뒤 요청하면 JSON으로 응답을 받게 된다.

Last updated