TIL 2021.04.24 [구현/문제해결] [Spring Data JDBC] [ResponseEntity]

kyukim·2021년 4월 24일
0

TIL

목록 보기
104/322

Http 응답코드와 함께 데이터 보내기

{
  "status": 200,
  "data": [
    {
      "category_id": ???,
      "name": ???,
      "items": [
        {
          "detail_hash": ???,
     	  ...
          ...
        }
      ]
    },
    {
      "category_id": ???,
      "name": ???,
      "items": [
        {
          ...
          ...
          ...
        }
      ]
    }
}
          

status 200이 여기에있는거면, 이면 Http 응답이 정상적으로 됐다는걸 데이터에 같이 담아서 response 하라는 말로 이해했다.
이건 어떻게 보내야하는 걸까..고민하다가, 지난 프로젝트 때, 백엔드 짝 코코가 컨트롤러에서 객체가 아니라 ResponseEntity에 아규먼트로 HttpStatus를 리턴해줬던 게 기억이나서 바로 ResponseEntity에 대해 찾아보기로 했다.

ResponseEntity

찾아본 결과 역시 ResponsEntity는 Http의 Header,Body 를 JSON 데이터로 같이 보내주고 싶을 때 사용하는 api이었다.

Message 라는 클래스를 따로 생성하고, 그 클래스 안에 실제로 보낼 데이터의 필드들을 작성해준다.

public class Message {
    public static final int OK = 200;
    public static final int BAD_REQUEST = 400;
    public static final int NOT_FOUND = 404;
    public static final int INTERNAL_SERVER_ERROR = 500;

    private int status;
    private Object data;

    public Message(int status, Object data) {
        this.status = status;
        this.data = data;
    }

    public int getStatus() {
        return status;
    }

    public Object getData() {
        return data;
    }
}

나는 위와 같이 작성했다.
예제에보니까 상수 부분은 enum으로 돼있던데, 그냥 나같은 경우엔 Message 클래스 안에 static final로 나열하는 게 가독성이 더 좋아보여서 저렇게 했다.

이렇게 만든 Message를 Controller에서 ResponseEntity<?>의 제너릭 부분에 넣어주고 return 해주면 된다

    @GetMapping("/best")
    public ResponseEntity<Message> findAllBestBanchans() {
        List<CategoryDto> categoryDtoList = categoryService.findAllBestBanchansByCategories();
        Message message = new Message(Message.OK, categoryDtoList);
        return new ResponseEntity(message, HttpStatus.OK);
    }

제너릭의 사용 유무에 따라 어떻게 객체를 반환해주는지 아직 이해가 100% 되진 않았는데, 어쨋든 ResponseEntity에 저런식으로 Message와 HttpStatus 같이 보낼수있고, Header도 만들어서 중간에 끼워 넣을수있고, 아니면 단순히 HttpStatus를 보내기위해 String 값과 함께 넣어서 보낼수도 있다.

카테고리에 "따른" 아이템 전부 가져오기

    public List<CategoryDto> findAllBestBanchansByCategories() {
        Iterable<Category> categoryList = categoryRepository.findAll();
        Set<String> setOfCategoryIds = new HashSet<>();
        for (Category category : categoryList) {
            setOfCategoryIds.add(category.getCategory_id());
        }

        List<CategoryDto> categoryDtoList = new ArrayList<>();
        for (String category_id : setOfCategoryIds) {
            categoryDtoList.add(findBestBanchansByCategory(category_id));
        }
        return categoryDtoList;
    }

이번 프로젝트의 주요 고민들은 데이터를 어떻게 가져올 것인가였던거 같다.
맨 상단에 나온 JSON포맷대로 가져오기 위해서는

  1. HttpStatus 안에 데이터를 넣는다.
  2. 그 데이터는 카테리고리로 묶여진 아이템 리스트들이다.
  3. 그러므로 카테고리에 따른 리스트를 따로 만들어서 HttpStatus에 넣어줘야한다.

그 고민의 결과로 이번 코드는 3번을 충족시키기 위해서 만든 코드이다.
레포에서 바로 가져오는 방법이 있을지도 모르겠지만, 일단 이렇게 했다.

  1. findAll()로 카테고리의 레코드들을 Entity로 매칭된 Category로 가져온다.
  2. Category마다 category_id를 체크해서 Set에 넣어준다, 이때 중복된 값은 Set이기 때문에 자동으로 걸러진다.
  3. 그렇게 중복되지않은 category_id들이 담긴 Set을 가지고 이전에 만들었던 catoegory에 따라서 반찬들을 가져오는 메서드를 사용해서 카테고리 List를 만든다.
  4. 리턴.

0개의 댓글