api 기본 구조 작성하기

최준호·2022년 1월 7일
0

eats

목록 보기
7/13

api 패키지 만들기

api를 작성하기 위해 각 패키지를 만들어 패키지에 맞게 작동하도록 그리고 테스트 코드도 추가하여 작업할 수 있게 구조를 만드려고 한다.

우선 내가 지금 당장 필요하다고 생각되는 패키지들을 정의해놨다. 각각 패키지는

controller api 호출시 client의 요청과 parameter를 받아오는 곳
service 실제 서비스 로직이 실행되어지는 곳
repository 서비스 로직 중 db와 작업이 필요한 곳에서 db의 데이터를 가져오거나 넣어주는 곳
domain db테이블에 컬럼을 정의하거나 내가 사용할 모델을 사용하는 곳
exception exception을 정의하는 곳
advice exception처리를 하기 위한 곳

이렇게 사용하기 위해 작성했다.

공통 처리 만들기

api를 사용하면서 공통적으로 response하는 형태나 공통으로 반환되는 exception을 처리해야할 경우가 있다. 또한 이 공통 response나 exeception를 상속받아 다른 response나 exception을 추가하면 되므로 기본 뼈대가 되는 공통 처리 모델들이다.

공통 response

@Getter
@Builder
@AllArgsConstructor
public class CommonV1<T> {
    private String result;  //success, fail 구분
    private String code;    //api 고유 상태코드
    private String msg;     //반환 메세지
    private T data;         //반환 데이터

}

먼저 공통 response를 만들었다. response할 데이터들을 정의하였는데

result api 통신이 성공했는지 실패했는지 결과 값
code api 고유 상태코드
msg 필요하다면 메세지 전달
data 반환되는 데이터

로 정의 하였고 lombok 어노테이션의 경우

@Getter 변수들의 getter생성
@Builder 빌더 패턴 생성
@AllArgsConstructor 모든 변수들을 포함한 생성자 생성

이다.

test controller 만들기

위의 response대로 정말 반환되는지 확인해보기 위해 test controller를 작성해보자

@RestController
public class TestController {
    @GetMapping("/v1/test")
    public ResponseEntity test(){

        CommonV1.CommonV1Builder<Object> builder = CommonV1.builder();
        builder.result("success");
        builder.code("200");
        builder.data(null);
        builder.msg("성공");

        CommonV1 result = builder.build();
        return new ResponseEntity(result, HttpStatus.OK);
    }
}

test controller를 만들어 테스트해보면

내가 생각했던 결과를 return 받을 수 있다.

공통 error 처리

다음으로는 exception이 발생했을 때 error에 대한 처리가 필요한데 이를 처리해보자.

우선 CommonErrorV1 class를 만든다. response의 CommonV1과 마찬가지로 반환하기 위한 객체를 담을 클래스인데.

@Getter
@AllArgsConstructor
public class CommonErrorV1<T> {
    private T error;
}

다음과 같이 error들을 담을 것이기 때문에 이렇게 작성했다.

그리고 response와 다르게 error를 담아야하기 때문에 error 객체를 정의한 클래스도 만들어야하는데

@Getter
@AllArgsConstructor
public class CommonError {
    private String msg;
}

CommonError라는 클래스명으로 msg만 전달하도록 작성했다. 다른 전달하고 싶은 정보가 있다면 변수를 추가해서 전달하면 된다.

그러면 우리가 작성한 error를 반환할 수 있도록 설정을 해보자!

exception 만들기

간단한 exception을 하나 만들어보자.

@AllArgsConstructor
@Getter
public class CommonException extends RuntimeException{
    private String msg;
    private HttpStatus status;
}

Exception은 msg와 status를 전달하기위해 getter를 추가하여 작성했다.

advice 설정하기

@RestControllerAdvice
public class CommonAdvice {
    @ExceptionHandler(CommonException.class)
    public ResponseEntity commonExceptionAdvice(CommonException ce){
        List<CommonError> errorList = new ArrayList<>();
        CommonError commonError = new CommonError(ce.getMsg());
        errorList.add(commonError);

        CommonErrorV1<List<CommonError>> result = new CommonErrorV1<>(errorList);
        return new ResponseEntity<CommonErrorV1>(result, ce.getStatus());
    }
}

에러 처리를 위해 다음과 같이 설정해주었다. 에러가 일어날 경우 여러 정보를 전송하기 위해 배열 형태로 처리하는 경우가 보편적이라 배열 형태로 생성했다.

test controller test

@GetMapping("/v1/error")
public ResponseEntity error(){

    CommonV1.CommonV1Builder<Object> builder = CommonV1.builder();
    builder.result("success");
    builder.code("200");
    builder.data(null);
    builder.msg("성공");

    CommonV1 result = builder.build();

    if(true) throw new CommonException("내가 만든 exception", HttpStatus.FOUND);
    return new ResponseEntity(result, HttpStatus.OK);
}

아까 만들어 두었던 test controller에 다음과 같이 코드를 추가하자.

코드를 보면 아까 전에 테스트와 거의 동일한데 마지막 return 전에 exception을 발생시키도록 처리해두었다.

exception이 정상적으로 에러로 처리되었고 상태 코드값과 메세지도 내가 작성한 내용 그대로 정상적으로 전달되었다!

이후 작업

이제 api를 작업할때 위 공통 class들을 상속받아 필요한 정보를 더 추가해서 작업하면 될것이다!

다음 작업은 rest docs를 추가해보자. api는 문서화가 필수니까!

builder 패턴으로 작업할때 참고하면 좋은 글을 찾았다.

builder 패턴에서 유효성 검사

profile
해당 주소로 이전하였습니다. 감사합니다. https://ililil9482.tistory.com

0개의 댓글