Intro
이 글에서는 Rest, Restful, Rest API 등 들어는 보았는데 정확히 어떤 내용인지를 몰랐던 것에 대해서 정리를 해보고자 한다.
기본적인 백엔드 구현과 관련이 있다고 생각되어서 스스로도 알아야 할 필요성을 느끼게 되엇다. 아래의 정보들은 나름대로의 자료를 조사하며 내가 이해한 바를 그대로 적고자 함이 가장 큰 목표이다. 만약 틀린 부분이 존재한다면 댓글에 남겨주시면 빠르게 파악하고 수정할 수 있도록 하겠습니다.
Rest(Representational State Transfer)
먼저 문자 그대로 해석을 해보자면, "표현 상태 전송" 이라는 뜻으로 해석이 됩니다.
그렇다면 무엇의 표현 전송해야 하는가? 하는 의문을 가지게 되었는데, 그 무엇은 우리가 말하는 자원(Resource)이 됩니다.
즉 웹 상에서 자원의 상태를 주고받으며 데이터를 전송하고 처리하는 방법을 정의한 인터페이스이다.
- 자원(Resource) : 해당 소프트웨어가 관리하는 모든 것(문서, 그림, DB 등..)
- 자원의 표현 : 내가 영화에 관한 데이터를 표현하고자 하면 소문자를 사용하고, book이 아닌 복수형 books를 사용.
- 자원의 상태 : 그 자원이 어떠한 상태를 가지고 있는가를 뜻함. 주로 JSON 혹은 XML을 이용해서 전송한다.
Rest의 경우 HTTP URI(쉽게는 인터넷 주소)를 통해서 자원을 명시하고(https://test.com/books와 같이) CRUD방식을 통해서 데이터를 전송하고 처리하게 된다. 기본적인 CRUD(Create(생성), Read(조회), Update(수정), Delete(삭제)) 를 HTTP Method(GET, POST, PUT, DELETE)를 통해서 처리한다.
만약, 내가 모든 책의 정보를 가지고 오고 싶다면 /getAllbooks 와 같은 방식이 아니라, /books에 GET요청을 보내면 된다.
그렇다면, 책을 추가하고 싶다면? /createBook 이 아니라 /books에 POST 요청을 보내서 처리하게 된다. 즉 하나의 URI를 통해서 2가지의 작업을 할 수 있게 된다. 조금 더 자세한 정보를 원한다면 예를 들면 GET 요청을 /books/harryporter와 같이 하면 가능해진다
REST의 특징
1. HTTP 프로토콜을 그대로 사용
- HTTP 라는 기존 웹 표준을 그대로 사용하기 때문에, 별도의 환경(인프라)의 구축이 필요하지 않다. 따라서 캐시 기능을 이용해서 같은 URI에 대해서 반복된 요청을 효율적으로 처리할 수 있게 된다.
2. Stateless하다(무상태성)
- Stateless한 것과 Stateless하지 않은 것에 대한 차이를 처음에는 이해하기 어려웠다. 내가 이해한 바를 간단히 설명하자면, 만약 A라는 곳으로 GET요청을 보냈을 때에, Kim이라는 사람과 Park이라는 사람이 다른 응답이 오게 되는것을 Stateful 하다 라는 의미를 한다고 파악했다. 하지만 REST의 경우 데이터의 변동이 있지 않은 이상 같은 요청에 대해서는 같은 응답을 보내게 되고 이를 Stateless 한 특징이라고 이야기하게 된다는 것으로 파악했다.
3. 서버 - 클라이언트 역할 분리
- 2번의 Stateless한 특징을 통해 가지게 되는 REST의 특징이다. GET 요청을 Kim이 보냈는 지, Park이 보냈는 지는 서버에서 중요하지 않기 때문에, 서버는 데이터만을 다루고 보내주는 역할만 할 수 있으며, 클라이언트는 이러한 데이터를 통해서 각각 요청자에 대해 데이터를 다룰 수 있다. 따라서 서로에 대한 의존성이 낮아지게 되며, 개발해야 할 내용을 명확히 할 수 있게 된다.
4. 계층형 구조
- 클라이언트 측에서 요청을 보낼 때에, 내가 메인 서버와 통신을 하는지, 중간 서버와 통신하는 지에 대해서는 알 수 없다. 이를 일상생활에 비유해보자면(실제와는 조금 다를 수 있다), 택배를 주문하였을 때에, 판매자가 직접 가져다줄 수도 있지만, 안전상의 이유로 믿음직한 택배업체를 통해서 가져다줄 수도 있다. 즉, 나(클라이언트)는 제대로 된 물건을 받는 것만 확인하면 되는 것이다. 이를 다시 개발이야기로 말해보자면, 클라이언트와 서버의 통신 사이에 보안이나 로드 밸런싱을 위한 중간 계층을 추가할 수 있다는 것이다.
(현실에서는 어느 택배사의 어느 기사님이 가져다주는지까지 알 수 있다 ㅎㅎ...)
REST의 장점
1. 쉬운 사용
- HTTP 프로토콜을 그대로 사용하기 때문에 REST를 사용하기 위한 별도의 환경을 구성하지 않아도 된다. 따라서, HTTP 프로토콜에 대해 공부하게 된다면 손쉽게 REST를 익힐 수 있다.
2. 범용적이다
- HTTP를 사용하는 플랫폼이라면 어느 곳에나 적용할 수 있다.
3. 특정 데이터 표현 가능
- REST API는 헤더 부분에 URI 처리 메소드를 명시하고 실제 필요한 정보는 body에 표현할 수 있도록 분리하였다. JSON, XML등으로 표현하게 된다.
REST의 단점
1. HTTP Method의 한계
- HTTP Method를 사용하기 때문에 REST의 경우 CRUD만을 할 수 있다.
2. 표준이 존재하지 않음
- 명확한 표준이 존재하지 않기 때문에 사용자 나름대로 변경될 수 있다. 예를 들어서 내가 어떠한 자원을 제거하는 데 있어 DELETE method가 아닌 POST method를 사용할 수도 있다.
- 혹은, UnAuthorized일 경우 401, Bad Request의 경우 400번의 HTTP 응답 코드를 보내야 하는데, 사용자 임의대로 200으로 합쳐버리고 세부 내용에서 어떠한 에러인지 정하게 할 수도 있을 것이다. 실제 기능을 하는데 있어서는 문제가 되지 않을 수도 있지만, REST적인 관점에서는 이러한 것을 안티패턴이라고 한다.
REST API
REST API에 대해서 이야기 하기 전에, API란 것이 무엇인지 간단히 정리를 해보고자 한다.
API(Application Programming Interface)란?
- 먼저 위키백과에 따르자면, "API란 컴퓨터나 컴퓨터 프로그램 사이의 연결이다. 일종의 소프트웨어 인터페이스이며 다른 종류의 소프트웨어에 서비스를 제공한다." 고 되어있다. 사실 이러한 정의만 보았을 때는 전혀 이해할 수가 없었다.
- 인터넷에 가장 많이 나와있는 예시를 하나 들어보도록 하겠다. 배가 고팠던 나는 맛있는 음식을 먹으러 근처의 식당에 방문하게 되었다. 자리를 잡고 앉자, 직원이 나에게 다가와 메뉴판을 건네주었고, 나는 파스타를 주문했다. 점원은 요리사에게 가서 파스타 주문이 들어왔다는 사실을 알리게 되었고 직원이 가져온 파스타를 맛있게 먹게 되었다. 그렇다면 이 예시가 API와 왜 관련되어 있는 것일까?
- 결론부터 말하자면, 위 예시에서는 직원이 API에 해당하게 된다. 나의 경우 직원이 가져온 메뉴판에서 선택할 수 있는 메뉴 중에서 메뉴를 골랐고, 직원은 그 요청을 요리사에게 전달했다. 요리사는 요청에 따라 파스타를 조리해서 응답했다. 직원은 그 응답을 파스타라는 결과물로 나에게 전달했다.
- 이를 컴퓨터로 예시를 들어보자면, 바탕화면에 "내 컴퓨터", "크롬(웹 브라우저)", "게임" 등 내가 선택할 수 있는 선택지(메뉴판)가 있었다. 내가 게임을 더블클릭을 하면 API는 이를 컴퓨터에게 전달하고 컴퓨터는 게임을 실행하는 내용(파스타)을 API를 통해서 나에게 보내주었다. 즉, 점원과 같은 역할을 하였다.
그렇다면 REST API란?
- REST를 기반으로 서비스 API를 구현한 것이다. 즉, 웹 상에서 사용되는 여러 자원들을 HTTP URI로 표현하고, 이러한 자원에 대한 행위를 HTTP Method를 통해 정의하는 방식이다.
REST API는 설계하기 위한 디자인 가이드가 존재한다!
1. URI는 정보의 자원을 표현해야 한다.
- 동사보다는 명사, 대문자보다는 소문자를 사용해야 한다.
- 도큐먼트 이름으로는 단수 명사를 사용해야 한다.
- 컬렉션 이름으로는 복수 명사를 사용해야 한다.
- 스토어 이름으로는 복수 명사를 사용해야 한다.
- 컨트롤러 이름으로는 예외적으로 동사를 사용한다.
* 도큐먼트란, 하나의 객체단위로 하는 단일 정보이다.(member소속의 팀원A 등)
* 컬렉션이란, 도큐먼트들의 집합이며, 관리 주체는 서버이다.(팀원들을 관리하는 member 등)
* 스토어란, 컬렉션과 같은 도큐먼트들의 집합이지만, 관리 주체는 클라이언트이다.(쇼핑몰 장바구니 등)
* 컨트롤러란, 컬렉션과 스토어의 메서드 기능이다. 기존의 CRUD 기능만으로는 구현할 수 없는 사항들을 뜻한다. 이를 표현하는 경우, 예외적으로 동사의 사용을 허용한다(IsExist 등)
2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.
- URI에 행위를 표현하지 않는다. (GET /delete/member/a, 대신 DELETE /member/a 등으로 표현)
- URI는 행위를 표현하는 것 보다는, 자원을 표현하는 것에 더 중점을 두어야 한다.
3. 슬래쉬(/) 구분자는 계층 관계를 나타내는 데 사용한다.
- /team/member/a 등 팀의 멤버 a 를 순차적으로 표현
4. URI 마지막에 슬래쉬(/)를 포함하지 않는다.
- /team/member/a/ (X)
5. 하이픈(-)은 URI 가독성을 높이는 데에 사용한다.
- 불가피하게 긴 URI경로를 사용하게 된다면, 하이픈을 이용해서 가독성을 높일 수 있다.
- ex) /user/postcomment 대신, /user/post-comment 를 사용해 가독성을 높임
6. 밑줄(_)은 URI에 사용하지 않는다.
- 밑줄은 경우에 따라 파악하기 힘들거나 밑줄 때문에 문자를 제대로 인식하지 못할 수 있으므로 사용하지 않는다.
7. URI 경로로는 소문자를 사용한다.
- 대문자와 소문자를 다른 리소스로 파악하기 때문에 URI경로는 소문자로 통일한다.
8. 파일 확장자는 URI에 포함하지 않는다.
- REST API에서는 메시지 바디 내용이 이미지인지, 동영상인지, 파일인지 등에 대한 정보를 URI가 아닌 HTTP Header의 Accept를 사용한다.
RESTful
위에서, REST, REST API등에 대해 알아 봤다. 그렇다면 RESTful이라는 것은 무엇일까? 쉽게 생각하자면, 이것은 REST를 지켰으므로, REST하다~ 라는 표현을 뜻한다. 조금 더 정확하게는, RESTful은 일반적으로 REST라는 아키텍쳐를 구현하는 웹 서비스를 나타내기 위해 사용되는 용어이다.(REST API를 제공하는 웹 서비스를 "RESTful하다"라고 할 수 있다.)
RESTful의 목적
- 이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것이다.
- 기능 및 성능상의 문제보다는 일관적인 통일성(컨벤션)을 통해 API에 대한 이해 및 사용 호환성을 높이는 것이 주된 목적이다.
- 만일 내가 지금까지 abcd처럼 표현하는 REST API를 만들다가 다른 API를 사용하는 데, 외부 API는 aBcD처럼 표현을 한다면 이를 이해하는 것부터 시간을 소요해야 하기 때문에 나온 것이 아닐까 하는 생각이 든다.
- 상위 REST의 단점에서 이야기한 것처럼, 표준이 없기 때문에 안티 패턴이 존재할 수 있고, 안티 패턴의 구조를 사용한다면 RESTful하지 못하다고 이야기할 수 있을 것 같다.
지금까지, 백엔드를 설계한다면 REST API를 설계한다고 해서, 그냥 어떻게 어떻게 되는 대로 따라서 사용을 했다. 근본적으로 REST라는 것이 무엇인지 모르기 때문에 스스로 공부를 하기 위해서 정리를 해 보았다. 사실, 경험이 많지 않아서 완벽하게 이해를 하고 사용을 할 수 있을 것이라는 확신은 없지만, 적어도 몰라서 못하는 상황은 없게 될 것 같다.
📒 작성된 내용 중에 틀린 부분이 있다면 언제나 지적해주시면 감사하겠습니다.
Reference(참고 자료)
https://grape-blog.tistory.com/8
https://tibetsandfox.tistory.com/19
https://velog.io/@yhlee9753/REST-API-와-HTTP-Stateless-에-대한-고찰
https://velog.io/@tenacious_mzzz/Stateless-vs-Statefulfeat.-Restful이란-무엇일까-후속편
https://round-round.tistory.com/entry/REST-API의-단점-3가지
'Back-End' 카테고리의 다른 글
[AWS] AWS, EC2, S3란 무엇일까? (0) | 2023.11.10 |
---|---|
[Java] Long? long? Wrapper Class에 대하여 (4) | 2023.11.09 |
[Spring] 스프링 DB 접근 기술 (0) | 2023.11.08 |
[Backend] 디자인패턴 - MVC패턴 (2) | 2023.10.09 |
[Backend] 백엔드 공부 시작 (0) | 2023.10.05 |
댓글