RestFul하다는게 무엇일까?

RestFul하다는 게 무슨 의미일까?

2023-12-31

RestFul하다?

RestFul하다는 게 무엇일까? RestFul은 그럼 왜 등장했고, 어떤 어려움을 해결하려고 했을까? 하나씩 알아보자!!

결론부터 말하자면 RESTFul은 REST를 잘 지킨 것이고 REST API는 REST로 잘 설계된 API를 지칭한다.

먼저 정의는 다음과 같이 되어있다.

RestFul API는 Rest API의 설계 원칙을 명확하게 지킴으로써, 
각 구성요소의 역할이 확실하게 분리되어 있어야 한다.

또한 각 리소스에 대한 기능을 HTTP 메소드 (POST,GET,PUT)등으로 일관되게 정의해야 한다.

설명만 들으면 추상적이고 어렵다. Rest API가 뭐고 구성요소의 역할...? 천천히 살펴보자.!! RestFul하다는 것을 알기전에 Rest가 뭐고 Rest API가 뭔지부터 살펴보자!!

마크다운 이미지

REST란

REST(Representational State Transfer)의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 것을 의미한다.

HTTP 기반에서 URI로 자원을 나타내고, Method로 Operation을 나타내는 것을 의미한다. 그리고 이런 형식을 따를 때 API가 RESTFul하다고 말한다.

그리고 REST는 6가지의 원칙과 제약을 갖는다. RESTFul한 API는 이 6가지의 원칙을 준수해야만 한다.

예를 들어보자. "이름이 KIM인 사용자를 생성한다"라는 호출이 존재한다면

이를 REST한 형태로 나타낸다면 아래와 같은 형태로 표현된다.

HTTP POST,http://example/users/
{
    users:{
        name:"KIM"
    }
}

생성한다는 행위가 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

마크다운 이미지

Stateless

각 요청은 서버에 다른 요청과 완전히 독립적이어야 한다. 즉, 이전 요청의 정보를 기반해 다음 요청을 처리하지 않는다.

무상태성을 구현하는 가장 일반적인 방법은 HTTP 세션이나 쿠키를 사용해 사용자 정보를 클라이언트 측에 심어두는 것이다. 이렇게 하면 서버는 클라이언트의 상태를 일일이 기억할 필요가 없다.

Cache

마크다운 이미지

클라이언트는 서버의 응답을 캐싱해 재사용할 수 있어야 한다. 이를 통해 클라이언트는 서버에 불필요한 요청을 보내는 것을 방지할 수 있다.

이때, cache-control 헤더를 통해 캐싱을 명시할 수 있다. 그럼 Next.js에서는 어떻게 cache-control을 줄 수 있을까? 공식문서를 읽어보자!

캐싱은 불필요한 외부 서버로의 요청을 줄일 수 있고, Next.js는 자동으로 /_next/static 폴더에 정적 자원(HTML,CSS 등)들에 대해 헤더를 추가하고 있다고 한다. 다음 헤더가 들어가게 된다.

Cache-Control: public, max-age=31536000, immutable

이 Cache-Control 헤더는 next.config.js에서 다시 조절할 수 있다. 이미 정적으로 만들어진 캐시에 대해 재검증이 필요하다면, page의 getStaticProps 함수로 할 수 있다. (Page 라우터 기준)

export async function getStaticProps(context) {
  return {
    props: {}, // 여기에 실제 데이터를 넣어 반환합니다.
    revalidate: 1, // 1초 후에 이 페이지의 캐시를 재검증합니다.
  }
}

next/image의 기본 로더를 사용하는 경우, minimumCacheTTL을 설정하여 이미지의 최소 캐시 유지 시간을 설정할 수 있다.

(13버전을 사용할 떄는 아예 다른 글로 정리할 생각이다!.!!)

Layered System(계층화된 시스템)

REST서버는 다중 계층으로 구성될 수 있고, 로드 밸런싱 등을 추가할 수 도 있고, PROXY서버와 같은 중간매체를 사용할 수 있게 한다!

클라이언트는 서버에 직접 연결되었는지, 중간 서버를 통해 연결되었는지 알 수 없어야 함을 의미한다.

마크다운 이미지

(클라이언트는 로드 밸런스로 띄운 서버에 연결되었는지, 직접 서버에 연결되었는지 알 필요가 전혀 없다)

Uniform Interface

구성요소(클라이언트, 서버 등)사이 인터페이스는 균일(uniform) 해야만 한다. 인터페이스를 일반화함으로써, 전체 시스템 아키텍쳐가 단순해지고, 구현과 서비스가 분리되고, 독립적인 진화가 가능하다.

Uniform Interface도 여러 제약 조건이 있는데 다음과 같다.

마크다운 이미지

예시를 들어보자. 회원 정보를 관리하는 API를 새로 만든다. 다음의 요구사항이 명시되어 있다.

자원은 URI로 식별되어야 한다. 그럼 지금 URI로 명시되어야만 하는 자원은 무엇일까??? 아마 회원 전체특정 회원이 될 것이다.

그럼 다음과 같은 URI로 자원을 식별할 수 있을 것이다.

화원 전체 조회 /members
특정 회원 조회 /members/{id}
특정 회원 등록 /members
특정 회원 수정 /members/{id}
특정 회원 삭제 /members/{id}

하지만 이렇게 되면 URI가 중복되는 문제가 발생한다. 자원을 조작할 때, HTTP 메시지에 정보를 담아야 하는 이유가 바로 이 떄문이다.

그럼 HTTP 메서드를 통해 HTTP 메시지에 자원에 대해 어떤 조작을 하는지 명시해보자!

//전체 회원 조회
/GET/members

//특정 회원 조회
/GET/members/${id}

// 특정 회원 생성
/POST/members

// 특정 회원 정보 업데이트
/PUT/members/{memberId}

// 특정 회원 정보 삭제
/DELETE/members/{memberId}

결국 RESTFul API의 핵심은 자원을 중심으로설계하는 것이라고 생각한다. URI로 자원을 식별하고 HTTP 메서드로 자원에 대한 조작을 명시한다.

추가적인 메소드들

PUT과 PATCH의 메소드는 요청된 자원의 전체/일부의 수정 여부에 따라 다르다. PUT 메소드는 요청된 자원의 전체를, PATCH메소드는 요청된 자원의 일부를 수정한다.

HEAD메소드는 GET방식과 동일하지만, HTTP Body가 없고 응답 코드와 HTTP Head만 응답한다. 특정 웹 페이지가 존재하는지 확인하고 싶을 때 사용할 수 있다.

HEAD/members/123 HTTP 1.1
HOST: www.example.com

이 요청은 example.com의 members/123이라는 자원에 대한 메타데이터를 요청한다. 해당 요청에 대한 응답은 메타데이터를 포함한 HTTP 헤더를 반환하게 된다.

HTTP/1.1 200 OK
Date: Sun, 18 Oct 2023 08:56:53 GMT
Server: Apache/2.4.1 (Unix)
Last-Modified: Sat, 20 Jul 2023 11:16:38 GMT
ETag: "45b6-4d2-4e1cf1a4"
Accept-Ranges: bytes
Content-Length: 1234
Vary: Accept-Encoding
Content-Type: text/html

마크다운 이미지

Options메소드는 웹 서버에서 지원되는 메소드의 종류를 확인할 때 사용할 수 있다. 응답은 다음과 같은 형태로 올 것이다!!

HTTP/1.1 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 0
Date: Sun, 18 Oct 2023 08:56:53 GMT
Server: Apache/2.4.1 (Unix)