쉼이 넘치는 API?? 아쉽게도 RestfulAPI에서 Rest는 휴식의 의미가 아니다. REST란 Representational State Transfer 의 약자로 소프트웨어 프로그램 개발 아키텍처의 한 형식이다. 이걸 한글로 어느정도 의미를 파악한다면, '자원(resource)의 표현(representation)에 의한 상태 전달' 이라고 할 수 있다.
그렇다면, Restful API는 이걸 적용한 API 아닐까? 더 깊이 빠고들어보자.
자원에 표현에 의한 상태 전달이 즉, REST라고 했다. 그렇다면 내가 알아들을 수 있는 설명은 무엇일까?
자원의 표현
- 자원은 해당 소프트웨어가 관리하는 모든 것을 의미한다. 문서, 그림, 데이터, 해당 소프트웨어 자체 등, 정말 모든 것을 의미한다.
- 자원의 표현은 그 소프트웨어가 관리하는 자원을 표현하기 위한 이름이다. 예를 들어, DB의 고양이 정보가 자원이라고 하면, "Cats"를 자원의 표현으로 정한다.
상태전달
개발 아키텍쳐의 한 형식인 REST는 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기에 웹의 장점을 최대한 활용하고 또 네트워크 상에서 클라이언트와 서버 사이의 통신 방식 중 하나이다.
조금 더 자세히 설명하면, REST는 자원 기반의 구조 (Resource Oriented Architecture) 설계의 중심에서 HTTP URI (Uniform Resource Identifier)로 Method를 수행해 통해 자원(Resource)를 표현하고 HTTP Methods (Post, Get, Put, Delete)을 판별해 해당 자원에 적절한 CRUD 작업 (상태전달)을 적용하는 것이다.
웹 사이트의 이미지, 텍스트, DB 내용 등 모든 자원에 고유한 ID 인 HTTP URI부여한다.
자원(Resource): URI
행위(Verb): HTTP Method
표현 (Representation of Resource)
서버-클라이언트 구조
Stateless(무상태성)
Cacheable
웹에서 사용하는 기존의 인프라를 그대로 활용할 수 있기에 HTTP의 가장 강력한 기능 중 하나인 캐싱 기능을 적용할 수 있다.
캐싱을 사용하면 대량의 요청을 효율적으로 처리할 수 있고 응답시간이 빨라진다. REST Server Transaction이 발생하지 않기에 전체 응답시간, 성능, 서버의 자원 이용률을 향상시킬 수 있다. (Last-Modified, E-Tag)
Layered System(계층화)
Self-descriptiveness(자체 표현 구조)
Uniform Interface(인터페이스 일관성)
{
"departmentId": 10,
"departmentName": "Administration",
"locationId": 1700,
"managerId": 200,
"links": [
{
"href": "10/employees",
"rel": "employees",
"type" : "GET"
}
]
}
이런식으로 response에 링크가 담겨 온다.
도큐먼트: 객체 인스턴스나 디비 레코드와 유사한 개념
컬렉션: 서버에서 관리하는 디렉터리라는 리소스
스토어: 클라이언트에서 관리하는 리소스 저장소
URI는 정보의 자원을 표현해야 한다.
ex) GET /Cats/1 -> /GET /cats/1
직관적인 REST API를 위해 컬렉션과 다큐먼트를 사용할 때 단수 복수를 지켜주면 훨씬 이해하기 좋다.
자원에 대한 행위는 HTTP Method로 표현한다.
리소스 간의 관계 표현하는 법.
REST 리소스 간의 연관 관계는 특정 표현 방법을 사용해야 한다.
/리소스명/리소스 ID/관계가 있는 다른 리소스명
ex) GET: /cats/{catid}/posts (일반적인 소유 관계를 표현)
관계명이 복잡할 시 서브 리소시에 명시적으로 표현할 수 있다. 고양이를 팔로우하는 유저의 목록 경우는 다음과 같은 형태로 사용할 수 있다.
ex) GET: /cats/{catid}/follows/users
URI의 마지막문자로 슬래시를 포함하지 않아야 한다.
슬래시 구분자는 계층 관계를 나타내는데 사용해야 한다. ( /cats/posts)
너무 긴 경로는 하이픈을 사용해서 가독성을 높인다.
URI의 마지막문자로 슬래시를 포함하지 않는다.
너무 긴 경로는 하이픈을 사용해서 가독성을 높인다.
밑줄은 사용하지 않는다.
소문자가 적합하니 URI에는 소문자를 사용한다.
파일확장자는 URI에 포함하지 않는다. 어셉트 헤더를 사용한다.
ex) /cats/10/photo.png (X)
ex) /cats/10/photo HTTP/1.1 Host: dedicats.com Accept:image/png (O)
REST API의 규칙을 어기면, RESTful 하다고 볼 수 없다.
ex) 모든 CRUD가 POST로만 처리된다.
ex) route에 resource, id 외의 정보가 들어가는 경우 (/cats/updateName)
항상 API 작성 시 어떨 때 어떤 상태코드를 응답해줘야 할지 고민했는데, 참고한 사이트에 너무 좋은 리소스가 있어 내 블로그에 옮겨오고 싶었다. 완벽하게 자세하고 명확하진 않지만, 들어있는 설명이 너무 이해하기 좋았다. 상태코드를 구체적으로 나누어주는게 장기적으로 좋다고 생각한다.
RESTful API를 목적으로 자주 서버 코드를 개발했지만, 이렇게 자세히 이론적으로 학습한 것은 처음인 것 같다. 이렇게 많은 규칙이 있는 지 몰랐고, 또 지금까지 내가 무엇을 잘못하고 있었는지도 알 수 있었다. 특히 URI 관련 규칙들을 공부하며 많은 것을 배울 수 있었고 다음부터는 URI 설계를 할 때 고려해야 할 점들을 숙지했다. 지금까지 작성한 API URI들을 보며 고쳐야겠다고 다짐했다. REST API는 흔히 쓰기 때문에 정확하게 알아야 하고 꾸준한 복습이 필요할 것 같다. 대충하지 않고, 정확히 이해하고 싶은 마음이 크다.
명확한 표준이 없기에 REST API를 사용시 개발하는 서비스의 특징과 개발 집단의 환경과 성향등이 충분히 고려되어 설계되어야 한다.
참고
https://meetup.toast.com/posts/92
https://blog.restcase.com/7-rules-for-rest-api-uri-design/
https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
https://restfulapi.net/hateoas/