윤개발

Api 정상, 에러 응답 공통 포맷 개발 본문

백엔드/스프링

Api 정상, 에러 응답 공통 포맷 개발

DEV_SJ 2021. 4. 28. 13:29

 

정상처리 및 오류처리에 대한 API 서버 공통 응답 포맷을 개발해보도록 하겠습니다. 공통 포맷을 개발하면 아래와 같은 장점이 있습니다.

  • Api 서버는 정상, 에러에 대한 응답의 포맷이 동일하며 어떠한 응답도 공통포맷 형태로 반환하면 됩니다.
  • Api를 사용하는 클라이언트는 공통 포맷을 보고 정상응답, 에러를 구분할 수 있습니다.

 

1. 응답 포맷 요구사항

공통 응답에 대한 요구사항은 다음과 같습니다. 

 

  • 정상, 오류처리 모두 success 필드를 포함합니다.
    • 정상처리라면 true, 오류처리라면 false 값을 출력합니다.
  • 정상처리는 response 필드를 포함하고 error 필드는 null 입니다.
    • 응답 데이터는 객체로 표현됩니다.
  • 오류처리는 error 필드를 포함하고 response 필드는 null 입니다. error 필드는 status, message 필드를 포함합니다.
    • status : HTTP Response status code 값과 동일한 값을 출력해야 합니다.
    • message : 오류 메시지가 출력 됩니다.

요구사항에 대한 응답예시는 다음과 같습니다.

 

2. 응답 포맷 예시

- 정상처리 응답 예시

{
  "success": true,
  "response": [
    {
      "name": "p1",
      "age": 1
    },
    {
      "name": "p2",
      "age": 2
    },
    {
      "name": "p3",
      "age": 3
    }
  ],
  "apiError": null
}

 

 

- 에러처리 응답 예시

{
  "success": false,
  "response": null,
  "apiError": {
    "message": "error",
    "status": 400
  }
}

 

3. 스프링 부트 생성 및 의존성 추가

Spring Initializer로 애플리케이션을 생성하고 아래 의존성을 추가합니다.

jackson 라이브러리는 객체를 json 형태로 반환해주는 라이브러리 입니다. jackson을 통해 객체를 response 값에 넣어서 반환할 것입니다.

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.12.3</version>
        </dependency>

패키지 및 클래스는 다음과 같이 구분하였습니다.

 

4. ApiResult, ApiError 객체 생성

다음으로 응답에 사용될 ApiResult 객체를 생성합니다. 제너릭을 통해 어떠한 객체가 들어와도 사용할 수 있도록 구현합니다.

@Getter
@Setter
public class ApiResult<T>{
    private final boolean success;
    private final T response;
    private final ApiError apiError;
    public ApiResult(boolean success, T response, ApiError apiError) {
        this.success = success;
        this.response = response;
        this.apiError = apiError;
    }
}

요구사항에 맞게 success 는 boolean 값, response에는 응답 값 에러가 있다면 ApiError를 이용합니다.

ApiError 는 다음과 같습니다.

@Getter
@Setter
public class ApiError{
    private final String message;
    private final int status;

    public ApiError(String message, int status) {
        this.message = message;
        this.status = status;
    }
}

 

에러메시지와 함께 에러코드를 가지는 간단한 클래스입니다.

 

5. ApiUtils 생성

이제 ApiUtils를 통해 정적 메소드로 반환하도록 해보곘습니다. 

public class ApiUtils {
    public static <T>ApiResult<T> success(T response) {
        return new ApiResult<>(true, response, null);
    }

    public static ApiResult<?> error(String message, int status){
        return new ApiResult<>(false, null, new ApiError(message, status));
    }
}

 

success 메소드는 응답값이 정상일때 호출하고 error는 ControllerAdvice 나 다른 에러처리 구간에서 호출하도록 하면 됩니다.

정적 팩토리 메소드는 다음 글을 확인해주세요 codinghack.tistory.com/17?category=846652

 

[ITEM1] 생성자 대신 정적 팩토리 메소드를 고려하라.

생성자 대신 정적 팩터리 메서드를 고려하라. 클래스의 인스턴스를 얻는 전통적인 방법은 public 생성자다. 하지만 클래스는 생성자와 별도로 정적 팩토리 메서드를 제공할 수 있다. 생성자보다

codinghack.tistory.com

 

6. 임의 객체 생성 및 테스트

다음으로 테스트를 위해 Controller와 Person 객체를 생성하겠습니다.

person 객체는 다음과 같이 간단한 구조입니다.

@Getter
@Setter
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static Person createPerson(String name, int age){
        return new Person(name, age);
    }
}

컨트롤러에서는 Person 배열을 반환하는 메소드와 임의로 에러를 생성하는 메소드를 구현하였습니다.

@Controller
@ResponseBody
@RequestMapping("/api")
public class CommonController {

    @RequestMapping("/person")
    public ApiResult<ArrayList<Person>> successApiFormat(){
        ArrayList<Person> people = new ArrayList<>();
        people.add(Person.createPerson("p1", 1));
        people.add(Person.createPerson("p2", 2));
        return ApiUtils.success(people);
    }

    @RequestMapping("/error")
    public ApiResult failApiFormat(){
        return ApiUtils.error("error",400);
    }
}

 

정상 응답에 해당하는 url에 접근하면 다음과 같이 응답값이 나오게됩니다.

에러 응답값

7. 다음에 할일

이것으로 공통 응답에 대한 개발을 완료하였습니다.

앞으로는 api 반환값은 response에 넣어 반환하면 되지만 에러처리 부분이 명확하지 않습니다.

에러처리는 ControllerAdvice를 공부해보시면 될 것 같으며 아래 포스트를 확인해주시기 바랍니다.

codinghack.tistory.com/66?category=897888

 

Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(8) - 에러처리 구현

에러처리 구현 이번 포스팅에서는 이전에 완료하지 못했던 에러처리에 대해 설명합니다. 에러처리에는 여러 방법이 있으나 이번 게시판에서는 네이버에서 사용하는 에러처리방법을 사용해보

codinghack.tistory.com

감사합니다.

'백엔드 > 스프링' 카테고리의 다른 글

스프링의 컴포넌트 스캔  (0) 2021.05.10
웹어플리케이션과 싱글톤  (0) 2021.05.10
Spring Security 공식 문서 정리  (0) 2021.04.19
Spring Security 원리 및 방식 정리  (0) 2021.03.22
스프링 부트 알아보기  (0) 2019.10.15
Comments