본문 바로가기
내가 공부하려고 올리는/IT 잡다

프로젝트 RESTful하게 API 수정하기

by 결딴력 2022. 7. 15.
반응형

 

✅ REST API


프로젝트를 리뷰하면서

작성한 많은 API가 RESTful하지 않다는 생각이 들었습니다.

 

우선 REST API의 구성요소에서 제일 핵심은 다음 두 가지입니다.

1. 자원(Resource)

2. 행위(Resource Methods)

 

URI는 정보의 자원을 표현하고

자원에 대한 행위는 HTTP Methods(GET, POST, PUT, DELETE)로 표현하는 것이죠.

 

실제 제가 만든 API입니다.

 

@RequestMapping("/board")
public class BoardController {

	@DeleteMapping("/delete/{study_id}")
    public ResponseEntity deleteStudy(@PathVariable("study_id") Integer study_id) {
    		//중략
    }

}

 

해당 컨트롤러를 호출하는 URI는 다음과 같습니다.

 

DELETE /board/delete/{study_id}

 

이 방식은 과연 REST를 제대로 적용한 URI일까요?

 

URI는 자원을 최대한 간결하게 표현해야 합니다.

동사형보다는 명사형을 사용합니다.

 

그렇다면 리소스가 어떤 행위를 할지는 어떻게 나타낼까요?

그것이 바로 HTTP Methods의 역할입니다.

 

URI로 자원의 행위를 나타내는 것이 아닌

HTTP Methods로 URI의 행위를 나타내는 것입니다.

 

따라서 같은 URI라도 HTTP Methods에 따라 다르게 동작할 수 있습니다.

 

예시를 보겠습니다.

GET /board/{id}
DELETE /board/{id}
POST /board/{id}
PUT /board/{id}

 

위의 URI는 모두 동일하나 HTTP Methods가 서로 다릅니다.

이 경우 GET은 게시글을 조회하는 데

DELETE는 게시글을 삭제하는 데

POST는 게시글을 작성하는 데

PUT은 게시글을 수정하는 데 사용할 수 있습니다.

 

이런 방식으로 자원을 적절하게 사용한 URI

적절한 HTTP Methods를 사용하는 것

좋은 REST API를 만드는 방법이 될 것입니다.

 

 

 

 

 

✅ 실제 프로젝트 RESTful하게 수정


이제 실제 프로젝트를 RESTful 하게 수정 해보겠습니다.

 

우선 앞서 언급한 URI입니다.

@DeleteMapping으로 적절한 메서드를 선언했기 때문에

'delete'와 같은 리소스는 필요하지 않습니다.

//이전
@DeleteMapping("/delete/{study_id}")
    public ResponseEntity deleteStudy(@PathVariable("study_id") Integer study_id)

이 코드를 다음과 같이 수정합니다.

 

//이후
@DeleteMapping("/{study_id}")
    public ResponseEntity deleteStudy(@PathVariable("study_id") Integer study_id) throws Exception {

 

☝ 게시글 세부 보기 컨트롤러도 수정합니다.

 

//이전
@GetMapping("/result/{id}")
public String getStudyBoard(Model model,
                            HttpServletRequest request,
                            @PathVariable Integer id)

 

기존 코드는 위와 같이 '/result/'라는 사용하지 않아도 되는 리소스가 사용됐습니다.

 

'/result'를 지우고 '/board/{id}'로만 표현할 수 있도록 변경합니다.

 

//이후
@GetMapping("/{id}")
public String getStudyBoard(Model model,
                            HttpServletRequest request,
                            @PathVariable Integer id)

 

 

 댓글 관련 컨트롤러입니다.

 

 //댓글 저장
 @PostMapping("/comments/save/{writer_id}")
 
 //대댓글 저장
 @PostMapping("/comments/save/reply/{writer_id}")
 
 //댓글 수정
 @PutMapping("/comments/modify/reply/{writer_id}")
 
 //댓글 삭제
 @DeleteMapping("/comments/delete/reply/{comment_id}")

 

comments를 리소스로 사용하고

중간 리소스인 save, modify, delete는 삭제하겠습니다.

 

대댓글의 경우 댓글 저장과 구별할 필요가 있기 때문에

'reply'까지 리소스로 사용하겠습니다.

 

//댓글 작성
@PostMapping("/comments/{writer_id}")

//대댓글 작성
@PostMapping("/comments/reply/{writer_id}")

//댓글 수정
@PutMapping("/comments/{writer_id}")

//댓글 삭제
@DeleteMapping("/comments/{comment_id}")

 

 

 프로필 관련 클래스입니다.

 

//회원정보 수정 화면으로 이동
@GetMapping("/profile/edit/{id}")

//회원정보 수정
@PutMapping("/profile/update/{id}")

//회원정보 삭제
@DeleteMapping("/profile/delete/{id}")

 

회원정보 수정 화면으로 이동 URI의 경우

profile 리소스는 다른 컨트롤러에서 이미 사용 중이기 때문에

profile과 edit으로 리소스를 나눌 필요는 있었으나

굳이 두 개의 리소스를 모두 사용해야 하나라는 생각이 들었습니다.

때문에 해당 URI에서 'profile' 리소스를 사용하지 않기로 했습니다.

 

수정, 삭제의 경우 각각 'update'와 'delete' 리소스를 삭제하기로 했습니다.

//회원정보 수정 화면으로 이동
@GetMapping("/edit/{id}")

//회원정보 수정
@PutMapping("/profile/{id}")

//회원정보 삭제
@DeleteMapping("/profile/{id}")

 

 

 위시리스트 관련 컨트롤러입니다.

 

//위시리스트 저장
@PostMapping("/like/save/{id}")

//위시리스트 삭제
@DeleteMapping("/like/delete/{id}")

 

'save'와 'delete' 같은 리소스는 필요하지 않기 때문에 삭제하겠습니다.

 

//위시리스트 저장
@PostMapping("/like/{id}")

//위시리스트 삭제
@DeleteMapping("/like/{id}")

 

 

 

 

 마치며


물론 RESTful 한 API를 설계하는 데는

이것 외에도 신경 써야 할 부분이 많다고 생각합니다.

 

지금도 프로젝트가 REST API에 완전히 부합하다고 말하기엔

미흡한 부분이 많은 것 같습니다.

 

하지만 REST API에서 가장 중요한 요소인

'리소스(Resource)'와 'HTTP Methods'에 초점을 맞춰

현재 제가 아는 한에서 프로젝트를 조금 더 RESTful하게 수정해봤습니다.

 

혹시라도 해당 API 설계에 문제가 있거나

이견이 있으시면 언제든지 댓글 부탁드립니다!

 

반응형

댓글