REST API 설계 원칙: 실무에서 욕먹지 않는 7가지 규칙
/getUserList, /deleteUser?id=3 같은 API를 만들고 있다면 멈추세요. 동작이 되더라도 협업과 유지보수에서 비용이 큽니다. REST는 리소스(명사)를 URL로 표현하고, 동작은 HTTP 메서드로 표현하는 규칙입니다. 핵심 원칙만 짚어봅니다.
1. URL은 동사가 아니라 명사로
행위는 메서드가 표현하므로 URL에는 리소스 이름만 넣습니다.
나쁜 예: POST /createUser, GET /getUserById?id=3
좋은 예: POST /users, GET /users/3
복수형 명사(/users)를 쓰고, 계층은 /users/3/orders처럼 표현합니다.
2. HTTP 메서드로 동작 구분
| 메서드 | 용도 | 멱등성 |
|---|---|---|
| GET | 조회 | O |
| POST | 생성 | X |
| PUT | 전체 수정 | O |
| PATCH | 일부 수정 | X |
| DELETE | 삭제 | O |
멱등성이란 같은 요청을 여러 번 보내도 결과가 같은 성질입니다. 네트워크 재시도 설계 시 중요합니다.
3. 상태 코드를 정확하게
에러가 났는데 200을 주면 클라이언트가 실패를 감지하지 못합니다.
// Express 예시
app.post('/users', (req, res) => {
if (!req.body.email) {
return res.status(400).json({ error: '이메일은 필수입니다' });
}
const user = createUser(req.body);
return res.status(201).json(user); // 생성 성공은 201
});
자주 쓰는 코드: 200(성공), 201(생성), 400(잘못된 요청), 401(인증 필요), 403(권한 없음), 404(없음), 500(서버 오류).
4. 일관된 응답과 에러 포맷
{
"error": {
"code": "VALIDATION_ERROR",
"message": "이메일 형식이 올바르지 않습니다",
"field": "email"
}
}
모든 에러를 같은 구조로 내려주면 프론트엔드 처리가 단순해집니다.
5. 페이지네이션·필터·버저닝
GET /users?page=2&size=20&sort=createdAt,desc
GET /v1/users (URL 버저닝)
주의: 한 번에 전체 목록을 내려주는 API는 데이터가 커지면 반드시 터집니다. 처음부터 페이지네이션을 넣으세요.
마무리 체크리스트
- URL은 명사 복수형, 동작은 메서드로
- 에러는 4xx/5xx로 정확히
- 응답·에러 포맷 통일
- 목록 API엔 페이지네이션 기본 적용
- 공개 API라면 버저닝(/v1) 미리 도입
함께 보면 좋은 글
HTTP 상태 코드 한눈에: 200·301·401·403·404·500의 진짜 의미
2xx·3xx·4xx·5xx의 큰 그림과, 실무에서 헷갈리는 401 vs 403, 301 vs 302, 200 vs 204의 차이를 API 설계 관점에서 정리합니다.
CORS 에러, 도대체 왜 나는 걸까: 원리와 해결
브라우저의 동일 출처 정책, preflight(OPTIONS) 요청, Access-Control-Allow-* 헤더의 역할을 이해하면 CORS 에러는 더 이상 미스터리가 아닙니다.
Docker 입문: 이미지와 컨테이너 개념부터 첫 실행까지
이미지와 컨테이너의 차이가 헷갈리는 입문자를 위한 가이드입니다. Dockerfile 작성, build/run/exec 명령어, 그리고 실무에서 자주 쓰는 명령을 실제 예제로 익혀보세요.