REST는 자원(Resource)을 URI로 표현하고, 그 자원에 대한 행위를 HTTP 메서드로, 결과를 상태 코드로 표현하는 아키텍처 스타일이다. 이 원칙을 따르는 API를 RESTful API라고 부른다.
1. REST의 구성 요소
| 요소 | 의미 | 예 |
| 자원 (Resource) | URI로 식별되는 대상 | /orders/1001 |
| 행위 (Verb) | HTTP 메서드 | GET, POST, PUT, PATCH, DELETE |
| 표현 (Representation) | 자원의 상태를 담은 데이터 | JSON, XML |
2. REST 제약 조건
| 제약 | 의미 |
| Client-Server | 클라이언트와 서버의 역할 분리 |
| Stateless | 서버가 클라이언트 상태를 저장하지 않음. 요청마다 필요한 정보를 모두 담음 |
| Cacheable | 응답에 캐시 가능 여부를 표시 |
| Uniform Interface | 일관된 방식(URI + 메서드 + 표현)으로 자원 조작 |
| Layered System | 중간에 프록시·로드밸런서가 있어도 클라이언트는 모름 |
| Code on Demand (선택) | 서버가 실행 코드를 내려줄 수 있음 |
3. HTTP 메서드
| 메서드 | 의미 | 멱등 | 안전 | 요청 본문 |
| GET | 조회 | O | O | 없음 |
| POST | 생성 (하위 자원 추가), 기타 처리 | X | X | 있음 |
| PUT | 전체 교체 (없으면 생성) | O | X | 있음 |
| PATCH | 부분 수정 | 보장 안 됨 | X | 있음 |
| DELETE | 삭제 | O | X | 보통 없음 |
- 안전(Safe): 서버 상태를 바꾸지 않음
- 멱등(Idempotent): 같은 요청을 여러 번 보내도 결과(서버 상태)가 한 번 보낸 것과 같음. DELETE를 두 번 보내면 두 번째는 404일 수 있지만 서버 상태는 같으므로 멱등이다.
4. 상태 코드
| 범위 | 의미 | 자주 쓰는 코드 |
| 2xx | 성공 | 200 OK, 201 Created, 204 No Content |
| 3xx | 리다이렉트 | 301 영구 이동, 302/307 임시 이동, 304 Not Modified |
| 4xx | 클라이언트 오류 | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 429 Too Many Requests |
| 5xx | 서버 오류 | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
| 헷갈리는 쌍 | 차이 |
| 401 vs 403 | 401은 인증 안 됨(누군지 모름, 로그인 필요), 403은 인증은 됐지만 권한 없음 |
| 400 vs 422 | 400은 형식 자체가 잘못됨, 422는 형식은 맞지만 값이 규칙 위반 |
| 301 vs 302 | 301은 영구 이동(검색엔진이 새 주소로 갱신), 302는 임시 이동 |
5. URI 설계 규칙
| 규칙 | 좋은 예 | 나쁜 예 |
| 자원은 명사, 복수형 | /orders | /getOrders |
| 행위는 메서드로 | DELETE /orders/1 | POST /orders/1/delete |
| 계층 관계는 경로로 | /members/42/orders | /orders?memberOrder=42 |
| 필터·정렬·페이징은 쿼리로 | /orders?status=PAID&page=2 | /orders/paid/page/2 |
| 소문자, 단어는 하이픈 | /delivery-addresses | /deliveryAddresses |
| 확장자 미포함 | /orders/1 + Accept 헤더 | /orders/1.json |
6. PUT vs PATCH vs POST
| 구분 | PUT | PATCH | POST |
| 의미 | 자원 전체를 보낸 내용으로 교체 | 보낸 필드만 수정 | 새 자원 생성 |
| 빠진 필드 | 비워짐(null) | 그대로 유지 | - |
| 멱등 | O | 구현에 따라 다름 | X |
POST가 멱등이 아니라서 결제·주문 생성처럼 중복이 치명적인 API는 클라이언트가 Idempotency-Key 헤더를 보내고 서버가 같은 키의 요청을 한 번만 처리하도록 만든다.
7. 실제로 어떻게 적용되나
- 결제 요청 재시도: 네트워크 타임아웃으로 응답을 못 받았을 때 클라이언트가 POST를 다시 보내면 결제가 두 번 될 수 있다. 멱등 키를 두어 같은 요청은 처음 결과를 그대로 돌려준다. 멱등성 개념이 실무에서 가장 크게 쓰이는 곳이다.
- 에러 응답 일관화: 상태 코드로 큰 분류를 하고, 본문에
{ code, message } 형태의 비즈니스 에러 코드를 담는다. 프론트는 401이면 로그인 페이지로, 403이면 권한 안내로 분기할 수 있다. - Stateless와 인증: 요청마다 토큰을 담아 보내면 서버가 상태를 저장하지 않아도 되어 서버를 늘리기 쉽다. 세션 방식이면 세션 저장소를 공유해야 한다.
- 레거시 URL:
/order/insertOrder.do 같은 동사형 URL은 REST가 아니라 RPC 스타일이다. 새 API는 /orders + POST로 설계하고, 기존 URL은 호환을 위해 유지하는 식으로 점진적으로 옮긴다.
8. 면접 질문으로 정리
- Q. REST란? 자원을 URI로 표현하고, HTTP 메서드로 행위를, 상태 코드로 결과를 표현하는 아키텍처 스타일이다. Stateless, 캐시 가능, 일관된 인터페이스 등의 제약을 따른다.
- Q. 멱등성이란? 어떤 메서드가 멱등인가? 같은 요청을 여러 번 보내도 서버 상태가 한 번 보낸 것과 같은 성질이다. GET, PUT, DELETE는 멱등이고 POST는 아니다.
- Q. PUT과 PATCH의 차이는? PUT은 자원 전체를 교체해 빠진 필드는 비워지고, PATCH는 보낸 필드만 부분 수정한다.
- Q. 401과 403의 차이는? 401은 인증되지 않은 상태(로그인 필요), 403은 인증은 되었지만 해당 자원에 대한 권한이 없는 상태다.