2020. 3. 15. 20:56

REST의 정의와 RESTful API란 무엇인가?

RESTful API란 무엇인가? 라는 질문을 받는다면 대충 REST한 구조로 서로 주고받는다라고 뭉퉁그려 알고있지만 제대로 된 정의가 무엇인지 한번에 대답하기는 힘들다. 정확히 REST한 구조란 무엇이고 이 구조를 사용한 RESTful한 API를 만든다는 것은 어떤 의미일까?

REST API혹은 Restful API에 대한 설명을 하기 전에 우선 REST에 대한 이해가 선행되어야 한다. REST란 Representational State Transfer의 약자로써 풀어서 설명하자면 자원을 이름으로 구분해 해당 자원의 상태를 주고받는 것을 말한다. 어떤 프레임워크가 아니라 이런 방식을 가지고 주고받겠다는 약속이라는 의미에서 코딩 컨벤션과 궤를 같이한다.

REST는 웹에 존재하는 자원(이미지, 동영상, DB)에 대해서 고유한 URI를 부여하고 활용하는 방법론을 의미한다.

REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다. 이는 로이 필딩에 의해 최초로 박사학위 논문에 소개되며 정의되었고, 로이 필딩은 HTTP의 주요 저자 중 한 사람으로서 그 당시 웹 설계의 우수성에 비해 제대로 사용되어지지 않는 모습에 안타까워하며 최대한 웹의 장점을 활용할 수 있는 이 아키텍처를 발표했다고 한다.

REST의 특징


Server-Client 구조

  • 일관적인 인터페이스로 분리되어 있어야 한다. 따라서 서로간의 의존성이 줄어든다.
  • 자원을 가진 쪽이 서버, 자원을 요청하는 쪽이 클라이언트가 된다.
  • 흔히 말하는 백앤드, 프론트앤드의 나누는 기준이 된다.

Stateless(무상태)

  • 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안 된다.
  • HTTP 프로토콜의 장점을 극대화 하기 위한 방법이므로 REST 역시 HTTP 프로토콜처럼 Stateless Protocol의 성질을 갖는다.
  • 세션 정보나 쿠키 정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 클라이언의 요청만을 단순 처리하면 된다.→서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않아 구현이 단순해지는 장점이 있다.

Cacheable(캐시 처리 가능)

  • WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.
  • 잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상시킨다.
  • 웹 표준 HTTP 프로토콜을 그대로 사용하므로 웹에서 사용하는 기존의 인프라를 그대로 활용할 수 있다.

Self-descriptiveness(자체 표현 구조)

  • REST API 메시지만 보고도 이를 쉽게 이해할 수 있도록 JSON을 이용해 직관적으로 이해가 가능한 자체 표현 구조로 되어있다,
  • 동사(Method) + 명사(URI) 로 이루어져있어 어떤 메서드에 무슨 행위를 하는지 알 수 있다.

계층형 구조

  • REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게한다.
  • API 서버는 순수한 비즈니스 로직을 수행하고 그 앞단에 보안, 로드밸런싱, 암호화, 사용자 인증 등을 추가하여 구조상의 유연성을 줄 수 있다.

 

REST의 구성


REST API는 다음과 같은 구성으로 이루어져 있다.

  • 자원(Resource): URI는 정보의 자원을 표현해야 한다.
  • 행위(Verb): HTTP Method
  • 표현(Representation of Resource): 자원에 대한 행위는 HTTP Method(GET,POST,PUT,DELETE)로 표현한다.

요약하자면 URI로 주어나 목적어를 만들고, HTTP Method로 동사를 만든다는 개념이다.

 

REST의 목표


  • 구성 요소 상호작용의 규모 확장성
  • 인터페이스의 범용성
  • 구성 요소의 독립적인 배포
  • 중간적 구성요소를 이용해 응답 지연 감소, 보안을 강화, 레거시 시스템을 인캡슐레이션

REST의 목표를 가지고 작업을 하게된다면 백앤드와 프론트앤드의 영역을 효율적으로 분리할 수 있어서 규모 확장에 있어서 장점이 생기고 각자 독립적으로 배포되어 버전 관리를 할 수 있다.

자원과 직접적인 통신을 하고 있는 백앤드가 분리되어있기 때문에 접근하는 것에 있어서나 자원을 캡슐화해서 보낼 수 있어서 보안도 강화되는 장점이 있다.

 

RESTful API


그렇다면 이 REST에서 파생된 RESTful API는 어떤 것일까. 말 그대로 위에 나열된 REST 아키텍처를 준수해 설계된 API를 말한다. REST와 RESTful을 동일한 의미로 사용되곤 하는데 엄격하게 따지자면 서로 다르다는 것을 알 수 있다.

API의 개념은 이미 이전 글에서 다룬적이 있다. 최근 코로나 때문에 대두되고 있는 공공기관 OpenAPI(누구나 사용할 수 있도록 공개된 API)나 다른 맵 API 등을 제공하는 대부분의 업체는 이 REST API 방식으로 API를 제공한다.

실제 이 RESTful하게 짜여진 API는 어떤 방식으로 자원을 주고 받을까? 위에 설명된 URI와 HTTP 메소드를 활용하는 것이 가장 대표적인 예이다.

 

URI 설계시 주의할 점


  • 슬래시 구분자(/)는 계측 관계를 나타내는 것에 사용(예를 들어 게시판에 글쓰기를 나타내려면 게시판이 가장 큰 계층이므로 게시판이 먼저 나오고 그다음에 글쓰기를 표현하므로 board/write 이런식으로 URI를 표현할 수 있다.)
  • URI 마지막 문자로 슬래시(/)를 포함하지 않는다. (board/write/가 아니라 board/write로 표현한다.)
  • 하이픈(-)은 URI 가독성을 높이는데 사용 (게시판이 자유 게시판이라면 free-board/write 로 가독성을 높힐 수 있다)
  • 밑줄(_)은 URI에 사용하지 않는다. (free_board/write 보다는 free-board/write를 권장한다.)
  • URI 경로에는 소문자가 적합하다.
  • 파일확장자는 URI에 포함하지 않는다.

 

METHOD 역할
GET GET을 통해 해당 리소스를 조회한다. 리소스를 조회하고 해당 도큐먼트에 대한 자세한 정보를 가져온다.
POST POST를 통해 해당 uri를 요청하면 리소스를 생성한다.
PUT PUT을 통해 해당 리소스를 수정한다.
PATCH PATCH를 통해 해당 리소스를 수정한다.
DELETE

DELETE를 통해 해당 리소스를 삭제한다.

보통은 값을 읽을 때는 GET, 쓸때는 POST, 지울 때는 DELETE라고 생각해서 사용하거나 애매하다 싶으면 그냥 모두 POST로 던져서 해결하는 식의 주먹구구식의 일처리가 많다.

하지만 그렇다면 진정으로 RESTful한 방식에 가깝다고 할 수 없다. 상황에 맞게 그리고 상태에 맞게 자원을 관리해야한다. 그렇다면 어떨 때 POST방식으로 값을 보내고, GET방식으로 보내고 PUT과 PATCH는 왜 같은 수정인데 나뉘어져 있을까? 각각의 역할에 대해서 알아보자.

Get 방식

  • 클라이언트에서 서버로 데이터를 전달할 때, 주소 뒤에 "이름"과 "값"이 결합된 스트링 형태로 전달
  • 주소창에 쿼리 스트링이 그대로 보여지기 때문에 보안성이 떨어진다.
  • 길이에 제한이 있다.(=전송 데이터의 한계가 있다.)
  • Post방식보다 상대적으로 전송 속도가 빠르다.

Post 방식

  • 일정 크기 이상의 데이터를 보내야 할 때 사용한다.
  • 서버로 보내기 전에 인코딩하고, 전송 후 서버에서는 다시 디코딩 작업을 한다.
  • 주소창에 전송하는 데이터의 정보가 노출되지 않아 Get방식에 비해 보안성이 높다.
  • 속도가 Get방식보다 느리다.
  • 쿼리스트링(문자열) 데이터 뿐만 아니라, 라디오 버튼, 텍스트 박스 같은 객체들의 값도 전송가능.

 

GET방식과 POST방식의 차이점


  • Get은 주로 웹 브라우저가 웹 서버에 데이터를 요청할 때 사용
  • Post는 웹 브라우저가 웹 서버에 데이터를 전달하기 위해 사용.
  • Get을 사용하면 웹 브라우저에서 웹 서버로 전달되는 데이터가 인코딩되어 URL에 붙는다.
  • Post방식은 전달되는 데이터가 URL에 표시되지 않는다.
  • Get방식은 전달되는 데이터가 255개의 문자를 초과하면 문제가 발생할 수 있다.
  • 웹서버에 많은 데이터를 전달하기 위해서는 Post 방식을 사용하는 것이 바람직하다.

 

PUT과 PATCH의 차이


PUT은 자원의 전체 교체 및 수정이 필요할 때 사용하고, PATCH는 자원의 일부만 수정되거나 교체될 때 사용된다.

따라서 DB의 특정 칼럼만 수정하고자 한다면 PATCH를 사용하고 그게 아니라 전부다 수정되야하는 사항이라면 PUT을 사용하면 된다.

 

응답 상태 코드


상태코드 설명
200 클라이언트의 요청을 정상적으로 수행함
201 클라이언트가 어떠한 리소스 생성을 요청, 해당 리소스가 성공적으로 생성됨(POST를 통한 리소스를 생성 작업 시)
400 클라이언트의 요청이 부적절 할 경우 사용하는 응답 코드
401 클라이언트가 인증되지 않은 상태에서 보호된 리소스를 요청했을 때 사용하는 응답 코드(예:로그인 하지 않은 유저 로그인시)
403 유저 인증상태와 관계 없이 응답하고 싶지 않은 리소스를 클라이언트가 요청했을 때 사용하는 응답 코드(403 보다는 400이나 404를 사용할 것을 권고)
405 클라이언트가 요청한 리소스에서는 사용 불가능한 메소드를 이용했을 경우 사용하는 응답 코드
301 클라이언트가 요청한 리소스에 대한 URI가 변경 되었을 때 사용하는 응답 코드
500 서버에 문제가 있을 경우 사용하는 응답 코드

활용해서 RESTful한 API 요청을 보내보기


위 URI와 응답 상태, 메소드 등을 활용해서 직접 API를 요청해 본다고 가정하자. 예를 들어 게시물이나 회원 목록 등을 가져온다고 한다면 GET 방식으로 요청을 해야한다.

// GET방식으로 http://localhost:3000/free/list에 요청 200 OK의 응답을 받는다
[
{
	"id": 1,
	"title":"글 제목",
	"author":"작성자1"
},
{
	"id": 2,
	"title":"글 제목2",
	"author":"작성자2"
},
.
.
.
]

글 제목 리스트들을 json형식으로 프론트에서 가져와서 활용할 수 있다. 글 수정 같은 경우는 프론트에서 글의 id값을 가지고 POST 또는 PUT 방식으로 요청할 수 있다.

// PATCH 방식으로 http://localhost:3000/free/modify에 요청 이때 body에 id값이 담겨져서 넘어와야한다. 리턴 값으로 수정된 값들을 넘겨준다.
// 200 OK의 응답을 받는다.
{
	"id":1,
	"title":"수정된 제목",
	"author":"작성자1",
	"content":"글 수정을 해봤어요~"
}

스스로에게 질문해보기


  • RESTful하다는 것은 어떤 것을 의미하는가?
  • 회원가입 요청을 보내려고 할 때 사용되어야하는 메소드와 상태코드가 무엇인가?