DELETE 요청을 POST로? (24.05.10)

YJ·2024년 5월 10일
post-thumbnail

블로그 작성법
목표 > 공부한 내용 > 얻었고, 앞으로 이걸 해봐야지 적기

✋ 수업 목표

  • Iterator, for - each에 대해 공부해보자.

🤔 공부한 내용

오전 프로젝트 정리

  1. product categoryId 있나?
    1.5 상품 등록할 때 부터... categoryId
  2. controller - service - reposiotory 분기 처리
  • repository 카테고리 id 에 해당하는 상품 리스트 반환

Controller에서 분기 처리하자.
API 짜기에 편리하다.

Iterator vs for - each

Iterator
자바 컬렉션 API(Framework) 인터페이스 중 하나
컬렉션 객체 요소 하나하나에 접근

  1. ArrayList
    for
ArrayList<String> sportStarts = new ArrayList<>();
        // add 이름 5개
        // 1. 순수한 for문 돌려서 순서대로 이름 출력
        sportStarts.add("이천수");
        sportStarts.add("말디니");
        sportStarts.add("황성빈");
        sportStarts.add("양현종");
        sportStarts.add("황재균");

        for(int i = 0; i < sportStarts.size(); i++) {
            System.out.println(sportStarts.get(i));
        }

Iterator

        Iterator<String> sportStarIterator = sportStarts.iterator();
        while(sportStarIterator.hasNext()) {
            System.out.println(sportStarIterator.next());
        }
  1. Map
    for
 // 2. map으로 바꾸기
        Map<Integer, String > fruits = new HashMap<Integer, String>();
        fruits.put(1, "체리쥬빌레");
        fruits.put(2, "사과");
        fruits.put(3, "파인애플");
        fruits.put(4, "바나나");
        fruits.put(5, "블루베리");

        for(int i = 1; i < fruits.size(); i++) {
            System.out.println(fruits.get(i));
        }

Iterator

// 4. fruits -> Iterator
        Iterator<String> fruitsIterator = fruits.values().iterator();
        while(fruitsIterator.hasNext()) {
            System.out.println(fruitsIterator.next());
        }

for each는 Iterator와 for문의 합작

 for (String sportStart : sportStars) {
            System.out.println(sportStart);
        }

for (String fruit : fruits.values()) {
     System.out.println(fruit);
}

for each의 단점

  1. 처음부터 끝까지 다 꺼냄(if문 걸고 break해서 나오면 되긴 함)
  2. Iterator로 변경하여 반복하지 않으면, 수정 불가
    예시 코드
for (String sportStar : sportStars) {
    System.out.println(sportStar);

    if (sportStar == "황재균") 
                    sportStars.remove(sportStar);
            }

여러 개를 삭제하는 API

방법들..

  • DELETE + body [배열] : 웹 브라우저 따라 무시하는 애들도..
  • URL parameter : 안정성 (GET 제외)
  • Id 여러 개 : URL parameter / body

위 방법들이 있지만 아래 방법을 추천 한다.

POST method는 body로 값을 숨기고 싶을 때 사용할 수 있다.

그러면, POST method를 사용하여 DELETE를 한다?
delete의 의미를 어디다가는 담아야 하지 않을까?
라는 생각이다.
담을 수 있는 방법으로 URL에 의미를 담는 것을 추천한다.

Delete에 body 값을 권장하지 않는 이유에 대한 자료
https://www.rfc-editor.org/search/rfc_search_detail.php?sortkey=Number&sorting=DESC&page=All&pubstatus%5B%5D=Standards%20Track&std_trk=Internet%20Standard

  1. 상품 id는 중요한 정보가 아니여서 URL에 담아도 된다.
  2. 그러나, URL에 여러 정보를 담기에는 무리가 있다.
  3. 그래서 배열을 body에 담으려고 한다.
  4. 그러나, delete는 body를 무시하는 경우가 있어 delete method를 포기한다.
  5. 그래서 POST method를 사용하고, url에 delete를 명시하여 삭제의 의미를 담는다.

/products/delete
/delete-products

이런 식으로 url을 작성할 수 있다.

HTTP method delete

상품을 삭제하는 API를 요청한다.
그러고, 잘 삭제되었는지 확인하기 위해 어떻게 해야할까?

  1. map일 경우 remove해서 성공하면 객체 반환, 실패하면 null
  2. Controller에서 삭제 실행 후 조회를 하면 어떻게 될까?

나는 map.remove()의 반환값으로 성공 여부를 판단하였다.

delete의 body로 배열을 전달할 때

@PostMapping("/products/delete")
    public ResponseEntity deleteProducts(@RequestBody Map<String, List<Integer>> deleteRequest) {
        List<Integer> productIds = deleteRequest.get("productIds");

        if (productIds.isEmpty()) {
            log.info("productIds가 없어");
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        productService.deleteProducts(productIds);
        return new ResponseEntity<>(HttpStatus.OK);
    }

java 세상에서의 명명법

java 세상에서는 camelCase로 변수명을 작성하자.
sql에서 snakeCase를 사용한다고 하더라도
java에서는 java의 명명법을 따르자.

😉 앞으로 이걸 해봐야지

DELETE 메서드를 사용할때 body를 전달할 필요가 있을 경우에는 POST 메서드를 사용하고, URL에 delete라는 것을 명시해볼 것 이다. 또한, for - each, Iterator 등 반복에 대한 새로운 개념들을 코드에 적용해봐야겠다.

profile
dev

0개의 댓글