REST API와 RESTful API의 차이점을 알아보자
REST란
REpresentational State Transfer의 약자로 하이퍼미디어 시스템을 연결하는데 사용되는 스타일인 표현 상태 전송 아키텍처 형식이다.
1. REST는 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있다는 장점이 있다.
2. REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 중 하나이다.
REST의 핵심 원칙
1. 클라이언트 - 서버 구조 : 사용자 인터페이스와 데이터 저장소를 분리하여 각각의 독립적인 발전을 가능하게 한다. 클라이언트는 사용자 인터페이스에 집중하고, 서버는 데이터 저장과 처리에 집중한다.
2. 무상태성(Stateless) : 서버는 클라이언트의 상태 정보를 저장하지 않는다. 각 요청은 필요한 모든 정보를 포함해야 되며, 서버는 이전 요청에 대한 정보를 기억하지 않는다.
3. 캐시 가능성 : 응답 데이터는 캐시 가능 여부를 명시해야 한다. 적절한 캐싱을 통해 네트워크 효율성을 높이고 사용자 경험을 개선할 수 있다.
4. 계층화된 시스템 : 클라이언트와 서버 사이에 프록시, 게이트웨이 방화벽 등의 중간 계층을 둘 수 있다. 이를 통해 시스템의 확장성과 보안성을 향상시킬 수 있다.
5. 통일된 인터페이스: 리소스 식별, 표현을 통한 리소스 조작, 자기 서술적 메시지, 애플리케이션 상태의 엔진으로서의 하이퍼미디어(HATEOAS) 등의 제약을 따라야 한다.
6. 주문형 코드(선택사항): 서버가 클라이언트에게 실행 가능한 코드를 전송할 수 있다.
REST API란?
REST 아키텍처 스타일을 따라 설계된 API를 의미한다. 즉, REST는 개념이고 REST API는 그 개념을 구현한 실제 인터페이스이다.
그렇다면 REST API와 RESTful API의 차이는 무엇일까?
이 둘의 차이는 REST원칙 준수 정도에 있다.
REST API는 REST 아키텍처의 6가지 제약 조건을 모두 만족하는 API를 의미한다.
특히 HATEOAS(Hypermedia As The Engine Of Application State) 원칙까지 완전한 구현한 API이다.
※ HATEOAS : 하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다.
기본적으로 요청에 대해 서버는 응답에 데이터만 클라이언트에게 보내는데, HATEOAS를 사용하면 응답에 데이터뿐만 아니라 해당 데이터와 관련된 요청에 필요한 URI를 응답에 포함하여 반환하며, 이는 REST API를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 해준다.
RESTful API는 REST API의 구성 요소를 따르면서, URI와 HTTP 메소드를 적절하게 사용해 자원을 조작하는 API를 구현한 것이다.
따라서 RESTful API는 REST API를 개선하고, 보다 일관성 있는 API를 구현할 수 있도록 해준다.
엔드포인트에 따른 차이점 예시:
RESTful API
클라이언트가 하드코딩된 URL 사용
GET /users/123
응답 :
{
"id": 123,
"name": "홍길동",
"email": "hong@example.com",
"status": "active"
}
완전한 REST API(HATEOAS 구현)
서버가 응답에 다음 단계의 링크를 동적으로 제공
GET /users/123
응답 :
{
"id": 123,
"name": "홍길동",
"email": "hong@example.com",
"status": "active",
"links": [
{
"rel": "self",
"href": "/users/123",
"method": "GET"
},
{
"rel": "edit",
"href": "/users/123",
"method": "PUT"
},
{
"rel": "delete",
"href": "/users/123",
"method": "DELETE"
},
{
"rel": "orders",
"href": "/users/123/orders",
"method": "GET"
}
]
}
상태에 따른 동적 링크 변화
계좌 잔액이 충분할 때:
{
"account_number": 12345,
"balance": 1000.00,
"links": [
{
"rel": "withdraw",
"href": "/accounts/12345/withdraw",
"method": "POST"
},
{
"rel": "transfer",
"href": "/accounts/12345/transfer",
"method": "POST"
},
{
"rel": "deposit",
"href": "/accounts/12345/deposit",
"method": "POST"
}
]
}
계좌가 마이너스일 때:
{
"account_number": 12345,
"balance": -25.00,
"links": [
{
"rel": "deposit",
"href": "/accounts/12345/deposit",
"method": "POST"
}
]
}
계좌가 마이너스 상태일 때는 입금만 가능하고 출금과 이체 링크는 제공되지 않는다.
완전한 REST API의 특징:
- 클라이언트는 초기 URI만 알면 되고, 이후 모든 행동은 서버가 제공하는 링크를 통해 수행
- 응답에 다음 가능한 행동들에 대한 하이퍼링크가 포함됨
- 클라이언트 코드가 서버 API 변경에 영향을 받지 않음
{
"user": {
"id": 123,
"name": "홍길동",
"links": [
{"rel": "self", "href": "/users/123"},
{"rel": "edit", "href": "/users/123", "method": "PUT"},
{"rel": "delete", "href": "/users/123", "method": "DELETE"},
{"rel": "orders", "href": "/users/123/orders"}
]
}
}
RESTful API의 특징:
- HTTP 메서드를 의미에 맞게 사용 (GET, POST, PUT, DELETE)
- 리소스 중심의 URL 설계 (/users, /orders)
- 적절한 HTTP 상태 코드 사용
- JSON/XML 등 표준 형식 사용
- 하지만 HATEOAS는 구현하지 않는 경우가 많음
{
"id": 123,
"name": "홍길동",
"email": "hong@example.com"
}
RESTful API
1. 리소스 중심 URL 설계 :
명사 사용, 동사 금지
좋은 예시:
GET /users # 사용자 목록 조회
GET /users/123 # 특정 사용자 조회
POST /users # 사용자 생성
PUT /users/123 # 사용자 전체 수정
DELETE /users/123 # 사용자 삭제
나쁜 예시:
GET /getUsers
POST /createUser
GET /deleteUser/123
계층 구조 표현
좋은 예시:
GET /users/123/orders # 특정 사용자의 주문 목록
GET /users/123/orders/456 # 특정 사용자의 특정 주문
POST /users/123/orders # 특정 사용자의 주문 생성
나쁜 예시:
GET /getUserOrders?userId=123
GET /ordersByUser/123
2. HTTP 메서드 적절한 사용
CRUD 매핑
- GET: 조회 (안전하고 멱등적)
- POST: 생성 (비멱등적)
- PUT: 전체 교체 (멱등적)
- PATCH: 부분 수정 (비멱등적)
- DELETE: 삭제 (멱등적)
GET /products # 상품 목록 조회
GET /products/123 # 특정 상품 조회
POST /products # 새 상품 생성
PUT /products/123 # 상품 전체 정보 교체
PATCH /products/123 # 상품 일부 정보 수정
DELETE /products/123 # 상품 삭제
3. HTTP 상태 코드 활용
성공 응답
- 200 OK: 요청 성공 (GET, PUT, PATCH)
- 201 Created: 리소스 생성 성공 (POST)
- 204 No Content: 성공했지만 반환할 데이터 없음 (DELETE)
클라이언트 오류
- 400 Bad Request: 잘못된 요청
- 401 Unauthorized: 인증 필요
- 403 Forbidden: 권한 없음
- 404 Not Found: 리소스 없음
- 409 Conflict: 리소스 충돌
서버 오류
- 500 Internal Server Error: 서버 내부 오류
4. 일관된 네이밍 규칙
URL 규칙
O 소문자와 하이픈 사용: /user-profiles /order-items
X 카멜케이스나 언더스코어: /userProfiles /order_items
JSON 필드명
O 카멜케이스 또는 스네이크케이스 일관성 유지:
{
"firstName": "길동",
"lastName": "홍"
}
또는
{
"first_name": "길동",
"last_name": "홍"
}
5. 버전 관리
URL 경로에 버전 포함
/api/v1/users
/api/v2/users
헤더를 통한 버전 관리
Accept: application/vnd.api+json;version=1
6. 페이징과 필터링
페이징
GET /users?page=1&limit=20
GET /users?offset=0&limit=20
필터링과 정렬
GET /products?category=electronics&sort=price&order=desc
GET /users?status=active&created_after=2024-01-01
7. 에러 응답 표준화
일관된 에러 형식
{
"error": {
"code": "VALIDATION_FAILED",
"message": "입력 데이터가 올바르지 않습니다",
"details": [
{
"field": "email",
"message": "올바른 이메일 형식이 아닙니다"
}
]
}
}
8. 보안 고려사항
HTTPS 사용 필수
민감한 정보 URL에 노출 금지
GET /users?password=123456
POST /auth/login (body에 포함)