REST 살펴보기
API 디자인과 REST
REST (Representational State Transfer)
🔹표현된 자원의 상태를 주고 받는 방법을 정리한 아키텍처 스타일
🔹 REST API는 REST를 준수하여 만든 API를 말한다
🔹web과 http의 장점을 최대한 활용할 수 있게 된다
REST를 잘 준수한 API를 RESTful하다고 한다 (RESTful API)
REST 제약 조건
🔹클라이언트 서버
🔹무상태성
🔹캐시
🔹일관화된 인터페이스 → 가장 큰 영향을 주는 제약 조건
🔹계층화된 시스템
🔹주문형 코드
일관화된 인터페이스
🔹자원에 대한 식별
🔹표현을 통한 자원에 대한 조작
🔹자기 서술적 메세지
🔹하이퍼미디어를 사용한 애플리케이션 상태표현
REST의 제약조건
첫 번째 제약 조건: Client-Server(클라이언트-서버)
- API를 통해 정보를 교환하는 주체는 클라이언트와 서버 구조를 가져야 한다.
- 클라이언트와 서버의 분리를 통해 서로 의존하지 않는 구조를 가져야 한다. (관심사의 분리)
두 번째 제약 조건: Stateless(무상태성)
- 클라이언트는 상태를 저장하지 않는다.
- 클라이언트의 각 리퀘스트는 서버가 리퀘스트를 이해하는 데에 필요한 모든 정보를 포함해야 한다.
세 번째 제약 조건: Cache(캐시)
- 데이터 복사본을 임시 저장 위치에 저장하여 보다 빠르게 액세스할 수 있도록 하는 프로세스인 캐싱을 통해 네트워크 효율성을 높인다.
- 리퀘스트에 대한 리스폰스에 캐시 가능 및 불가능 여부가 들어 있어야 한다.
네 번째 제약 조건: Uniform Interface(일관된 인터페이스)
- 전체 시스템을 잘 파악할 수 있도록 일관된 인터페이스를 제공해야 한다.
- 이를 통해 구현체가 서비스와 별도로 독립적으로 진화할 가능성을 얻게 된다. (낮은 결합도)
- 예를 들어 클라이언트가 업데이트되어도 서버를 함께 업데이트할 필요가 없어진다. (반대의 경우에도 해당)
다섯 번째 제약 조건: Layered System(계층화된 시스템)
- 클라이언트는 서버에 직접 연결되었는지, 중간 서버를 통해 연결되었는지 알 수 없어야 한다.
여섯 번째 제약 조건: Code on Demand(주문형 코드)
- 서버에서 보낸 코드를 클라이언트에서 실행할 수 있어야 한다. (e.g. JavaScript)
- 선택적 제약 조건이며 지키지 않아도 REST에는 문제가 없다.
URI
자원의 식별
→ 접근하고자 하는 자원을 명시하고, 그 자원을 식별할 수 있어야 한다
URI
🔹단수,복수, 식별자를 사용한다
URI 작성 규칙
명사형 사용
URI는 동작(동사)을 가리키는 대신에, 자원(명사)을 가리켜야 한다. 자원에는 속성이 있듯이, 명사는 동사가 가지지 않는 속성을 가지기 때문이다.
Bad ❌
/get-member-list
/create-new-member
Good ✅
/members
/articles
반환(응답)하는 자원의 종류에 따라 단수형/복수형 사용하기
여러 개의 자원을 반환한다면 복수형, 단 1개의 자원을 반환한다면 단수형을 사용한다.
/members # 멤버 목록 (복수형)
/members/1 # 멤버 목록 중 (복수형), 1번 멤버 (단수형)
/key # 1개의 키 (단수형)
계층 표현을 위하여, 슬래시(/) 사용
자원들 간의 계층 표현을 위해서 슬래시(/)를 사용한다.
/articles
/articles/1
/articles/1/comments
/articles/1/comments/2
마지막 슬래시(/) 붙이지 않기
마지막에 붙는 슬래시를 트레일링 슬래시 (Trailing Slash)라고 한다.마지막 슬래시는 REST에서 어떠한 의미도 가지지 않기 때문에 혼동을 줄 수 있다. 따라서 붙이지 않는다.
Bad ❌
/articles/1/comments/
Good ✅
/articles/1/comments
모두 소문자로 작성 & 띄어쓰기는 대시(``) 사용
언더스코어(_) 또는 카멜 케이스(CamelCase)는 가독성을 낮출 수 있기에 사용하지 않는다. 띄어쓰기를 위한 대시(-)와 함께 소문자를 사용한다.
Bad ❌
/articles/topVoted
/articles/top_voted
Good ✅
/articles/top-voted
파일 확장자 포함하지 않기
파일 확장자는 특정 파일을 가리키는지, 아니면 자원의 식별자인지 헷갈릴 수 있기에 넣지 않는다. 만약 HTML, JSON과 같은 미디어 타입을 강조하고 싶은 경우, Content-Type 헤더를 사용하여 전달한다.
Bad ❌
/articles.html
/members.json
Good ✅
/articles
/members
목록에 필터가 필요할 경우, 쿼리 문자열을 사용
/articles/1/comments?sort=latest
URI에 동사 사용하지 않기
HTTP 메소드만으로도 충분히 해당 내용을 표현할 수 있기 때문에, URI에 불필요한 동사를 사용하지 않는다.
Bad ❌
/members/1/delete
/members/2/update
Good ✅
DELETE /members/1
PUT /members/2
HTTP 메소드와 표현
HTTP Method
🔹자원을 다루는 행동
GET (자원 가져오기)
🔹가져오는 행동이므로 자원은 변화하지 않도록 해야한다
🔹여러 번 리퀘스트를 보내도 같은 리스폰스를 돌려준다
🔹 안전한(safe) 메소드
POST(자원 조작하기)
🔹자원에 대해 무언가를 수행하였기에 자원의 변화가 있다
🔹자원 목록에 데이터를 전송하여, 새로운 자원의 생성을 요청한다
PUT/PATCH (자원 수정하기)
🔹업데이트의 의미
DELETE (자원 삭제하기)
HTTP Method
🔹자원을 다루는 행동
GET (자원 가져오기)
🔹가져오는 행동이므로 자원은 변화하지 않도록 해야한다
🔹여러 번 리퀘스트를 보내도 같은 리스폰스를 돌려준다
🔹 안전한(safe) 메소드
POST(자원 조작하기)
🔹자원에 대해 무언가를 수행하였기에 자원의 변화가 있다
🔹자원 목록에 데이터를 전송하여, 새로운 자원의 생성을 요청한다
PUT/PATCH (자원 수정하기)
🔹업데이트의 의미
DELETE (자원 삭제하기)
POST vs PUT vs PATCH
PUT은 자원의 교체(replace), PATCH는 부분 수정(partial update)을 의미한다
id가 1인 멤버가 다음과 같은 속성을 가지고 있다고 가정한다.
{
"username": "harry",
"age": 30
PUT
- 리퀘스트
PUT /members/1
{
"username": "mike"
}
- 리스폰스
200 OK
{
"username": "mike",
"age": null
}
☑️ id가 1인 멤버의 자원을 리퀘스트에 포함된 자원으로 교체(replace)하였기 때문에, 리퀘스트로 전달되지 않은 자원의 속성은 비어 있는 상태로 수정되며, 자원의 표현 시 null로 표시한다.
PATCH
- 리퀘스트
PATCH /members/1
{
"username": "mike"
}
- 리스폰스
200 OK
{
"username": "mike",
"age": 30
}
☑️ id가 1인 멤버의 자원을 리퀘스트에 포함된 자원으로 **부분 수정(partial update)**하였기 때문에, 리퀘스트로 전달된 자원의 속성만 반영
미디어타입과 링크 헤더
리퀘스트와 리스폰스는 모두 문자로 주고 받는다
자기 서술적 메세지
🔹메세지는 보면 그 의미가 해석되어야한다
(따라서 메세지의 해석 방법을 같이 전달하는 경우가 많다)
Content-type: Media Type(미디어타입)
ex) json, html 등
🔹iana에서 미디어타입을 관리한다
HATEOAS
일관된 인터페이스엔 HATEOAS 제약 조건이 포함되어있다
링크 헤더
리스폰스 바디에 상태 변경을 위한 링크 포함
HAL을 사용한다 (JSON, XML등)
→ HAL은 리소스와 링크로 구성된다
캐싱
재사용을 위해 데이터를 저장하는 장소 → 캐싱
REST에는 캐싱이 가능해야한다는 조건이 있다
헤더
🔹캐싱할 자원을 판단
🔹클라이언트와 서버의 자원 정보를 전달
Cache-Control : 캐싱 방식
Last-Modified: 날짜
🔹데이터가 마지막으로 수정된 날짜를 가리킨다
Last-Modified의 한계
🔹날짜와 시간을 기반으로 하기에, 1초보다 작은 단위의 캐시 관리 불가능
🔹실제 자원의 변경 없이 수정된 시간만 변경된 경우에도 다른 데이로 인식
→ ETag 헤더를 사용하면 이러한 한계를 조금이라도 극복할 수 있다
ETag
API 버전 명시하기
추가와 삭제는 쉽게 되지만 변경은 그렇지 않다
현재 서비스에 영향을 주지 않도록 변경해야한다
→ 작은 변경 사항과 큰 변경사항으로 나눠짐
api의 큰 변경 사항
→ 새로운 엔드포인트를 만들어야할 수도 있다
- 새로운 엔드포인트 추가
- 클라이언트의 사용
- 기존 엔드포인트 제거
기존의 가리키는 자원은 같은데 새로운 엔드포인트로 너무 다른 url를 사용할 경우
버저닝
🔹웹 api에서의 버저닝은 엔드포인트에 붙인다
페이지네이션
🔹여러 자원들을 페이지로 묶어서 전달하는 것
'🏃♀️ 대외활동 > Codeit Boost-Node.js' 카테고리의 다른 글
10주차 스터디 Express 유저 기능 구현하기 [코드잇 부스트 백엔드 스터디 ] (0) | 2024.08.18 |
---|---|
9주차 스터디 유저 기능 원리 [코드잇 부스트 백엔드 스터디 ] (0) | 2024.07.31 |
9주차 스터디 Express 핵심 기능 [코드잇 부스트 백엔드 스터디 ] (0) | 2024.07.31 |
8주차 스터디 Git 명령어 및 개념 정리 [코드잇 부스트 백엔드 스터디] (0) | 2024.07.16 |
6주차 스터디 관계형 데이터베이스를 활용한 자바스크립트 서버 만들기(2) [코드잇 부스트 백엔드 스터디] (2) | 2024.07.03 |