REST란 Representational State Transfer 의 약자로 소프트웨어 프로그램 개발의 아키텍처의 한 형식입니다. Representational State Transfer- '대표적인 상태 전달' 이 단어만 듣고 REST가 무슨 뜻인지 알 수 있는 사람은 영어권에서도 없을 것이라고 생각이 되는데요, 저는 개인적으로 이 단어를 변형해서 '자원(resource)의 대표(representation)에 의한 상태 전달' 이라고 설명하려 합니다. 그럼 '자원의 대표'와 '상태 전달'이 무슨 뜻인지 알아봅시다.
여기서 '자원'이란 뜻은 넓은 의미로 해당 소프트웨어가 관리하는 모든 것이 될 수 있습니다. 문서가 될 수도 있고 그림이 될 수도 있고 데이터가 될 수도 있고 심지어 해당 소프트웨어 자체가 될 수도 있습니다. 예를 들어 DB에 학생 명부가 저장되어 있다고 한다면 이 학생들의 정보가 자원이 됩니다. 그리고 '자원의 대표'의 의미는 그 자원을 대표하기 위한 이름을 뜻합니다. 학생데이터를 대표하기 위한 이름은 무엇이 좋을까요? 물론 학생(students:복수형을 사용합니다)입니다. 학생 전체 명부가 아니라 명부상의 한 학생에 대한 자원을 얻고자 한다면 대표이름과 한 학생을 특정할 수 있는 값(id 등) 이 사용됩니다.
데이터가 요청되어지는 시점에서 자원의 상태(정보)를 전달하는 것을 뜻합니다. 데이터를 요청하는 시점에 따라 데이터가 바뀔 수도 있기 때문에 '상태'라는 표현을 쓴 것이라 추측해 봅니다. 프로그램이 학생 명부 전체 리스트를 요청받으면 요청받은 시점의 '상태' 즉 데이터를 전달하게 됩니다. 또한 새로운 학생 명부 '상태'를 프로그램에 전달하여 해당 자원을 수정할 수도 있습니다.
이처럼 자원을 이름으로 구분하고 해당 자원의 상태를 주고 받는 모든 것이 REST라고 할 수 있지만, 일반적으로 REST라고 하면 좁은 의미로 HTTP를 통해 CRUD를 실행하는 API를 뜻합니다.
HTTP 프로토콜을 이용하기 때문에 URL(route)를 통해 자원을 특정짓고 HTTP Verbs를 통해 할일(CRUD)을 지정합니다. 또한 JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적입니다.
위 정의에 더하여 REST를 정의하기 위한 조건들은 다음과 같습니다.
REST는 위 정의들을 구현하는 방식에 제약을 두지 않기 때문에 구체적인 가이드라인이 없습니다. RESTful은 REST의 비공식적 구현 가이드입니다. 반드시 따라야 하는 법칙을 만들어서 공표한 것이 아니라 여러 개발자들이 비공식적으로 의견을 제시한 것들의 모음으로. 즉 개발자마다 생각하는 RESTful의 내용이 다를 수도 있다는 것이죠.
RESTful 중 가장 대표적이며 보편적인 규칙이 확고하게 정해진 RESTful routing에 대해 알아봅시다. 참고로 이 외의 RESTful 에는 header의 사용, return 구조, error code의 사용법 등이 있습니다.
CRUD | HTTP verbs | Route |
resource들의 목록을 표시 | GET | /resource |
resource 하나의 내용을 표시 | GET | /resource/:id |
resource를 생성 | POST | /resource |
resource를 수정 | PUT | /resource/:id |
resource를 삭제 | DELETE | /resource/:id |
student resource(데이터)를 관리하는 API를 생각해봅시다. student resource는 id, 이름, 수강하고 있는 과목들의 정보를 가지고 있습니다. 아래는 student resource의 예입니다.
{ "id": 1, "firstName": "Tyrion", "lastName": "Lannister", "classes": [ {"id": 1, "name": "History of Westeros"}, {"id": 2, "name": "Brewing"}, {"id": 3, "name": "High Valyrian 101"} ] }
이제 이러한 데이터를 DB에 생성(Create)하고, 호출(Read)하고, 수정(Update)하고, 삭제(Delete)하는 CRUD route를 구상해 봅시다.
검색을 하기 위해서는 query를 사용합니다. Query_이름=Query_값의 형태로 url을 통해 전달되는 정보들을 query라고 합니다. url 뒤에 '?'를 붙인 후 query를 전달하며, 하나 이상의 query를 전달하기 위해서는 query들 사이에 '&'를 사용합니다. 성이 "Lannister"인 학생들을 검색하는 API의 주소는 [GET] /students?lastName=Lannister 로 설정할 수 있습니다. 물론 [GET] /students와는 별개로 해당 route을 처리하는 코드를 만들어 주어야 합니다.
RESTful하지 못한 예:
**아래는 2019년 5월에 추가된 내용입니다.
get을 제외한 HTTP verb들은 모두 그 구조와 사용법에 차이가 없습니다. get과 나머지의 차이점도 request body를 보낼 수 있고 없고의 차이 뿐입니다. (get은 request body를 보낼 수 없고, 나머지는 보낼 수 있습니다.)
즉, 프로그래머는 [PUT] /students/1를 student를 지우는 용도로, [DELETE] /students/1 를 student를 수정하는 용도로 만들어 사용 할 수도 있습니다. 이건 너무 극단적인 예제이고, RESTful routing 이 소개되기 전에는 대부분의 사람들이 아래와 같은 route을 사용했습니다.
[POST] /GetStudentList [POST] /GetStudent/:id [POST] /CreateStudent [POST] /UpdateStudent/:id [POST] /DeleteStudent/:id
한가지 짚고 넘어가야 하는 부분은, RESTful은 API를 설계하는 하나의 수단일 뿐이지 RESTful이 옳고 나머지가 틀린 것은 아닙니다.
트위터의 API를 살펴봅시다: https://developer.twitter.com/en/docs/tweets/post-and-engage/overview
get과 post만 사용되었고, route에 동사가 들어가는 전형적인 RESTful하지 않은 API입니다.
어떠한 사람들은 RESTful API의 주소가 복잡해 보여서 싫어하는 경우도 있습니다. 아래의 표를 살펴봅시다.
용도 | RESTful API 주소 | 비 RESTful API 주소 |
학생을 생성 | [POST] /students | /CreateStudent |
성으로 학생을 검색 | [GET] /students?lastName=성 | /SearchStudentByLastName |
이때 비 RESTful의 경우 모든 HTTP verb가 POST이므로 생략가능하고, SearchStudentByLastName의 경우 검색할 성은 request body에 들어갑니다. RESTful routing이 익숙하지 않은 사람눈에는 RESTful하지 않은 API 주소들이 더 이해하기 쉽습니다.
1. 정해진 규칙대로 routing 주소를 만들기 때문에 route 이름을 짓는 수고를 덜 수 있고, 통일성이 있습니다. 한 회사에 두개의 개발팀이 있습니다. 한 팀은 학생을 관리하는 API를 만들고, 다른 한팀은 교사를 관리하는 API를 만듭니다. 이때 두팀 모두 RESTful하게 API를 만들면 "students", "teachers"라는 resource 명을 제외한 나머지 API주소가 동일하게 됩니다. 만약 두팀이 RESTful하지 않게 API주소를 만든다면, 새로운 학생, 교사를 추가하는 API 주소는 /CreateStudent, /NewTeacher, /CreateNewStudent, /NewTeacher 등 다양하게 될 수 있고, 나중에 양쪽 팀의 API를 동시에 사용하는 프로그램을 만드는 경우 이러한 비일관성은 불필요한 혼란을 불러올 수 있습니다.
2. API의 확장이 쉽습니다. 학생 API에서 과목을 관리하는 API를 추가하는 경우, [POST] students/:id/classes, [DELETE] students/:id/classes/:id 등과 같이 만들 수 있습니다. 비 RESTful의 경우, 이 기능을 가지는 route의 주소이름을 따로 지어줘야 하는데.. 이름짓는데 시간과 노력이 들어가며, 그렇게 정해진 이름 역시 1번의 문제를 고스란히 가집니다.
통일성과 확장성이 RESTful API의 장점입니다. 정해진 규칙에 따라 API 주소, request구조, return 구조를 만들기 때문에 개발팀이 바뀌거나 하는 경우에도 혼란을 줄일 수 있습니다.
댓글
이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기