BackEnd
개발자라면 게다가 웹 개발자거나 Spring
개발자라면 적어도 한 번 이상,
아니 너무나 익숙하게 많이 들었을 것이다.
RESTful
하다는 게 대체 뭘까?
RESTful
: REST API
의 설계 의도를 명확하게 지킴으로써, 각 구성 요소들의 역할이 확실하게 분리 되어 있어서, URI
만 보더라도 리소스를 명확하게 인식 할 수 있도록 표현 한 설계 방식을 의미. 또한, 각 리소스에 대한 기능을 HTTP
메소드 (POST, GET, PUT, DELETE 등
)를 이용하여 일관되게 정의할 수 있어야 한다.
음... 🤔 어렵다. 그쵸?
개발자는 코드를 보면서 이해하는 것이 가장 빠르다.
실무에서 첫 API
를 설계할 때, 아래와 같이 URI
를 작성한 적이 있었다.
그리고 팀장님은 그런 나를 보시며 "RESTful
하다는거 글로 배웠죠 허허허 😊 " 라고 웃으며 말씀하셨다.
우리 팀장님 너무 좋으신 분이다. 안 혼내시고 인자하게 웃으시면서 말씀하신다. 하지만 팩트로 뼈를 퍽퍽
어떤 부분이 잘못되었을지 한번 봐보시라.
아, 예제 코드는 👉🏻 JPA를 사용한 카테고리 구현 시리즈에서 사용한 것을 가지고 왔다.
@PostMapping ("/category/save") @ResponseBody public Long saveCategory (CategoryDTO categoryDTO) { return categoryService.saveCategory(categoryDTO); } @GetMapping ("/category/get/{branch}") @ResponseBody public CategoryReturnDto getCategoryByBranch (@PathVariable String branch) { return categoryService.getCategoryByBranch(branch); } @PutMapping ("/category/update/{branch}/{code}") @ResponseBody public Long updateCategory (@PathVariable (name = "branch") @NotBlank String branch, @PathVariable (name = "code") @NotBlank String code, CategoryDTO categoryDTO) { return categoryService.updateCategory(branch, code,categoryDTO); } @DeleteMapping ("/category/delete/{branch}/{code}") @ResponseBody public void deleteCategory (@PathVariable (name = "branch") @NotBlank String branch, @PathVariable (name = "code") @NotBlank String code) { categoryService.deleteCategory(branch, code); }
주목해서 봐야할 부분은 각각의 매핑 어노테이션에서 URI
부분이다.
뭐가 잘못되었을까? 크게는 두가지다.
HTTP
메소드에서 정의 되어 있다.위의 메소드들은 각각의 기능들이 이미 HTTP
메소드를 통해 정의 되어있다.
저장하는 기능이면 POST
, 정보를 얻어 오는 것이면 GET
, 정보를 수정하는 것이면 PUT
, 삭제하는거면 DELETE
.
그러므로 굳이 URI
에 각각의 기능을 중복해서 적어줄 필요가 없다.
즉, 위의 RESTful
의 정의에서 "각 리소스에 대한 기능을 HTTP
메소드 (POST, GET, PUT, DELETE 등
)를 이용하여 일관되게 정의할 수 있어야 한다." 의 의미가 이런 의미다.
Category
객체를 URI
에 명시하여 이 API
를 통해서 Category
라는 객체를 관리할 것이라는 것을 알려줬다.
그러면, 관례적으로 객체명을 복수로 써 주는 것이 좋다.
@PostMapping ("/categories") @ResponseBody public Long saveCategory (CategoryDTO categoryDTO) { return categoryService.saveCategory(categoryDTO); } @GetMapping ("/categories/{branch}") @ResponseBody public CategoryReturnDto getCategoryByBranch (@PathVariable String branch) { return categoryService.getCategoryByBranch(branch); } @PutMapping ("/categories/{branch}/{code}") @ResponseBody public Long updateCategory (@PathVariable (name = "branch") @NotBlank String branch, @PathVariable (name = "code") @NotBlank String code, CategoryDTO categoryDTO) { return categoryService.updateCategory(branch, code,categoryDTO); } @DeleteMapping ("/categories/{branch}/{code}") @ResponseBody public void deleteCategory (@PathVariable (name = "branch") @NotBlank String branch, @PathVariable (name = "code") @NotBlank String code) { categoryService.deleteCategory(branch, code); }
RESTful
한 API
로 변경했다. 예제에는 적용되지 않았지만 사실 RESTful
하다는 의미를 충족시키기 위해서 여러가지 기준들이 있다.
팀장님 말씀에 의하면, 사실 기준이 다 다르고 누군가 확실하게 정의해 놓은 것이 없기 때문에 이걸 제대로 안한다고 해서 코드가 안돌아가는 것도 아니라고 하셨다. 욕은 먹을 수 있다.
RESTful
의 가장 중요한 건, URI
의 명확한 정의를 통해 실무에서 API
사용에 있어서 원할한 소통이 가능해야 한다는 것이다.
그 밖의 규칙들은 다음과 같다.
URI
를 표시할 때 계층들의 관계는 '/' 를 통해서 구분 해야한다.RESTful
한 API
는 가독성이 좋아야 하며, 보기만해도 어떤 의미인지 직관적으로 알 수 있어야 한다. 동사, 즉 메소드를 통한 어떠한 행위는 HTTP METHOD
를 통해서 충분히 어필이 되기 때문에 굳이 URI
에 써줄 필요가 없다. hwp
는 우리나라에서만 사용하는 확장자다. 나는 한글파일이 무척 싫다. 싫어 너무
가령 URI
에 minjae.com/board/zzang.hwp
로 되어 있다고 생각해보자. 우리나라 사람은 이게 뭔지 알겠지만, 외국인들은 하고 지나갈 것이다. shit
다시 강조하지만, RESTful
하다는 것은, URI
만 보고도 어떤 의미인지 직관적으로 알 수 있는 것이다.
사실, 더 깊게 들어가면 더 할 이야기가 많다.
이번 포스팅을 통해서 강조하고 싶은 것은 이거다.
RESTful
하다는 것은, 결국 소통이 원할한 API
를 구성하는 것.
개발자들에게는 코딩실력만큼 중요한건 소통이다. 💬
이 글을 읽는 모든 개발자가 소통도 짱짱 잘하는 좋은 개발자가 되시길 진심으로 빈다. 나도..