RestFul하다는게 무엇일까
RestFul하다는 게 무슨 의미일까?
2023-12-31
RestFul하다?
RestFul하다는 게 무엇일까? RestFul은 그럼 왜 등장했고, 어떤 어려움을 해결하려고 했을까? 하나씩 알아보자!!
결론부터 말하자면 RESTFul은 REST를 잘 지킨 것이고 REST API는 REST로 잘 설계된 API를 지칭한다.
먼저 정의는 다음과 같이 되어있다.
설명만 들으면 추상적이고 어렵다. Rest API가 뭐고 구성요소의 역할...? 천천히 살펴보자.!! RestFul하다는 것을 알기전에 Rest가 뭐고 Rest API가 뭔지부터 살펴보자!!
REST란
REST(Representational State Transfer)의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 것을 의미한다.
HTTP 기반에서 URI로 자원을 나타내고, Method로 Operation을 나타내는 것을 의미한다. 그리고 이런 형식을 따를 때 API가 RESTFul하다고 말한다.
그리고 REST는 6가지의 원칙과 제약을 갖는다. RESTFul한 API는 이 6가지의 원칙을 준수해야만 한다.
예를 들어보자. "이름이 KIM인 사용자를 생성한다"라는 호출이 존재한다면
- Resource = 사용자
- Method = 생성한다는 행위
- Message = 이름이 KIM인 사용자
이를 REST한 형태로 나타낸다면 아래와 같은 형태로 표현된다.
즉 생성한다는 행위가 HTTP POST 메서드가 되고, 생성하고자 하는 대상이 되는 사용자는 http://example/users라는 형태로 URI로 표현되며, 생성하고자 하는 사용자에 대한 내용은 JSON(다른 형태일 수 있음)으로 표현된다.
HTTP와 REST
REST는 결국 URL로 자원을 명시하고, HTTP Method로 제어를 내린다. 그 중 여러 Method가 있고, REST에서는 자원을 URI로 정한 뒤 , 알맞는 HTTP Method를 이용해 Message를 JSON이나 XML로 HTTP Body에 실어보내게 된다.
REST에 대해 제약 조건이 크게 6가지가 있다. 하나씩 살펴보자.!!
Client-Server
-
Client-Server 제약 조건은 API를 통해 정보를 교환하는 주체는 클라이언트와 서버구조를 가져야 합니다.
-
Client-Server를 서로 분리함으로써, 서로 의존하지 않는 구조를 가져야 합니다.
Stateless
각 요청은 서버에 다른 요청과 완전히 독립적이어야 한다. 즉, 이전 요청의 정보를 기반해 다음 요청을 처리하지 않는다.
-
클라이언트와 서버로의 요청에는 그 요청을 이해하는데 필요한 모든 정보를 포함해야 한다.
-
클라이언트와 서버 모두, 통신하는 상대의 상태를 저장하지 않는다.
-
요청과 응답이 들어올 떄마다, 상대가 누구인지 파악할 수 있어야 한다.
무상태성을 구현하는 가장 일반적인 방법은 HTTP 세션이나 쿠키를 사용해 사용자 정보를 클라이언트 측에 심어두는 것이다. 이렇게 하면 서버는 클라이언트의 상태를 일일이 기억할 필요가 없다.
Cache
클라이언트는 서버의 응답을 캐싱해 재사용할 수 있어야 한다. 이를 통해 클라이언트는 서버에 불필요한 요청을 보내는 것을 방지할 수 있다.
이때, cache-control 헤더를 통해 캐싱을 명시할 수 있다. 그럼 Next.js에서는 어떻게 cache-control을 줄 수 있을까? 공식문서를 읽어보자!
캐싱은 불필요한 외부 서버로의 요청을 줄일 수 있고, Next.js는 자동으로 /_next/static 폴더에 정적 자원(HTML,CSS 등)들에 대해 헤더를 추가하고 있다고 한다. 다음 헤더가 들어가게 된다.
이 Cache-Control 헤더는 next.config.js에서 다시 조절할 수 있다. 이미 정적으로 만들어진 캐시에 대해 재검증이 필요하다면, page의 getStaticProps 함수로 할 수 있다. (Page 라우터 기준)
next/image의 기본 로더를 사용하는 경우, minimumCacheTTL을 설정하여 이미지의 최소 캐시 유지 시간을 설정할 수 있다.
(13버전을 사용할 떄는 아예 다른 글로 정리할 생각이다!.!!)
Layered System(계층화된 시스템)
REST서버는 다중 계층으로 구성될 수 있고, 로드 밸런싱 등을 추가할 수 도 있고, PROXY서버와 같은 중간매체를 사용할 수 있게 한다!
클라이언트는 서버에 직접 연결되었는지, 중간 서버를 통해 연결되었는지 알 수 없어야 함을 의미한다.
(클라이언트는 로드 밸런스로 띄운 서버에 연결되었는지, 직접 서버에 연결되었는지 알 필요가 전혀 없다)
Uniform Interface
구성요소(클라이언트, 서버 등)사이 인터페이스는 균일(uniform) 해야만 한다. 인터페이스를 일반화함으로써, 전체 시스템 아키텍쳐가 단순해지고, 구현과 서비스가 분리되고, 독립적인 진화가 가능하다.
Uniform Interface도 여러 제약 조건이 있는데 다음과 같다.
- 자원은 URI로 식별되어야 한다.
- 자원을 조작할 때 (CRUD) HTTP메시지에 해당 내용을 담아 보내야 한다.
- 메시지는 스스로를 설명해야 한다.
- 애플리케이션의 상태는 하이퍼링크로 전이되어야 한다.
예시를 들어보자. 회원 정보를 관리하는 API를 새로 만든다. 다음의 요구사항이 명시되어 있다.
- 회원 목록을 조회할 수 있다.
- 회원을 조회할 수 있다.
- 신규 회원을 등록할 수 있다.
- 회원 정보를 수정할 수 있다.
- 회원을 삭제할 수 있다.
자원은 URI로 식별되어야 한다. 그럼 지금 URI로 명시되어야만 하는 자원은 무엇일까??? 아마 회원 전체와 특정 회원이 될 것이다.
그럼 다음과 같은 URI로 자원을 식별할 수 있을 것이다.
하지만 이렇게 되면 URI가 중복되는 문제가 발생한다. 자원을 조작할 때, HTTP 메시지에 정보를 담아야 하는 이유가 바로 이 떄문이다.
그럼 HTTP 메서드를 통해 HTTP 메시지에 자원에 대해 어떤 조작을 하는지 명시해보자!
결국 RESTFul API의 핵심은 자원을 중심으로설계하는 것이라고 생각한다. URI로 자원을 식별하고 HTTP 메서드로 자원에 대한 조작을 명시한다.
추가적인 메소드들
PUT과 PATCH의 메소드는 요청된 자원의 전체/일부의 수정 여부에 따라 다르다. PUT 메소드는 요청된 자원의 전체를, PATCH메소드는 요청된 자원의 일부를 수정한다.
HEAD메소드는 GET방식과 동일하지만, HTTP Body가 없고 응답 코드와 HTTP Head만 응답한다. 특정 웹 페이지가 존재하는지 확인하고 싶을 때 사용할 수 있다.
이 요청은 example.com의 members/123이라는 자원에 대한 메타데이터를 요청한다. 해당 요청에 대한 응답은 메타데이터를 포함한 HTTP 헤더를 반환하게 된다.
Options메소드는 웹 서버에서 지원되는 메소드의 종류를 확인할 때 사용할 수 있다. 응답은 다음과 같은 형태로 올 것이다!!