REST
Representational State Transfer
개념
데이터마다 주소를 붙여 두고 정해진 몇 가지 동작으로 그 주소를 읽고 쓰는 API 설계 방식입니다.
등장 배경
창구를 만들 때 이름과 규칙을 만드는 쪽이 자유롭게 정하던 시절이 있었습니다. 읽는 창구는 getUserInfo, 고치는 창구는 user_update, 지우는 창구는 deleteTheUser 가 됩니다. 각각은 이상하지 않은데 스무 개가 모이면 스무 가지 규칙이 됩니다.
그래서 붙이는 쪽의 부담이 컸습니다. 다른 회사 API 를 쓰려면 창구 목록을 끝까지 읽어야 하고, 읽어도 다음 이름을 짐작할 수 없습니다. 같은 회사 안에서도 목록을 불러오는 창구가 한 곳은 GET 이고 다른 곳은 POST 인 일이 흔했습니다.
REST 는 이 자유를 줄여 예측이 가능하게 만든 방식입니다. 창구마다 이름을 짓는 대신 데이터에 주소를 붙이고, 무엇을 할지는 정해진 몇 가지 동작으로만 말합니다. 규칙을 알면 문서를 다 읽지 않고도 다음 주소를 짐작합니다.
작동 방식
데이터 하나하나에 주소를 붙이고, 그 주소에 무엇을 할지는 정해진 동작 이름으로 말합니다. 다섯 가지를 지킵니다.
- 주소는 자원 이름으로 짓습니다. 동사를 넣지 않고 명사 복수형을 씁니다. 문서 목록은
/documents, 42번 문서는/documents/42입니다./getDocument는 동작이 주소에 섞여 있어 이 방식이 아닙니다. - 동작은 정해진 것만 씁니다. 읽기는
GET, 만들기는POST, 고치기는PUT이나PATCH, 지우기는DELETE입니다. 주소가 무엇을 가리키는지와 그것에 무엇을 하는지가 갈라져 있어, 새 자원이 생겨도 배울 것이 주소 하나뿐입니다. - 결과는 상태 코드로 알립니다. 정상은 200, 새로 만들었으면 201, 없는 주소는 404, 보낸 값이 잘못됐으면 400, 서버 쪽 문제면 500 입니다. 본문을 읽지 않고도 성공인지 실패인지 판단할 수 있다는 점이 값입니다.
- 서버가 부르는 쪽의 상태를 기억하지 않습니다. 요청 하나가 필요한 정보를 다 담아 오니 같은 사용자의 다음 요청이 다른 서버로 가도 됩니다. 서버를 열 대로 늘릴 때 앞에서 아무 데나 던지면 되는 이유입니다.
- 오가는 형식은 대개 JSON 입니다. 규격이 강제하지는 않지만 실무에서는 사실상 하나로 굳었습니다.
한계는 한 화면에 여러 자원이 필요할 때 드러납니다. 문서 상세 화면에 본문, 작성자, 댓글, 권한이 필요하면 주소 네 개를 각각 불러야 하고, 느린 회선에서는 그 네 번이 그대로 대기 시간이 됩니다. 각 주소가 정해진 항목을 다 돌려준다는 점도 비용입니다. 작성자 이름만 필요한데 가입일과 설정까지 옵니다.
쓰이는 곳
웹에서 바깥으로 창구를 열 때 기본값으로 씁니다. 규칙이 널리 알려져 있어 붙이는 쪽이 배울 것이 적고, 문서를 절반만 읽어도 나머지를 짐작합니다. 외부 개발자에게 공개하는 API 를 이 방식으로 만드는 이유입니다.
자원 모양이 뚜렷한 제품에 잘 맞습니다. 문서, 사용자, 팀, 댓글처럼 명사로 부를 수 있는 덩어리가 분명하면 주소가 자연스럽게 정해집니다. 반대로 "이번 달 매출을 지역별로 묶어 상위 다섯 개만" 같은 요청은 자원 하나로 부르기 어색해 주소가 복잡해집니다.
중간에 저장해 두기 쉽다는 점도 이유입니다. GET 은 읽기만 하니 같은 주소의 응답을 중간 서버에 잠시 보관해 다음 사람에게 그대로 줄 수 있습니다. 읽기가 많은 서비스에서는 이 하나로 서버 부담이 크게 줄어듭니다.
안 맞는 자리는 넷입니다. 화면마다 필요한 조합이 달라 호출이 다섯 번씩 나가는 앱이면 필요한 항목만 골라 받는 GraphQL이 낫습니다. 서비스끼리 초당 수천 번 주고받는 구간은 더 빠른 gRPC를 씁니다. 사건이 생겼을 때 서버가 먼저 알려야 하면 웹훅이고, 채팅이나 공동 편집처럼 양쪽이 계속 주고받아야 하면 연결을 열어 두는 웹소켓입니다.
실무 용례
"주소에 동사가 들어가 있어요.
/createDocument가 아니라/documents에 POST 입니다."
주소와 동작을 갈라야 한다는 지적입니다.
"이 화면 그리려고 네 번 부르고 있어요."
자원별로 나뉘어 있어 호출이 늘어난다는 말입니다.
"삭제인데 200을 주고 있네요. 204가 맞습니다."
상태 코드를 규칙대로 쓰자는 뜻입니다.
페이지덱은 외부 공개 API 를 이 방식으로 만들었습니다. 태오가 주소 규칙을 문서 한 장으로 정리해 두었고, 새 자원이 생길 때마다 그 규칙에 맞춰 주소를 추가합니다. 덕분에 "이건 어떻게 부르나요" 라는 문의가 거의 없습니다.
내부 창구는 다르게 갔습니다. 문서 상세 화면이 호출 다섯 번을 쓰고 있어서, 태오가 그 화면만 필요한 항목을 한 번에 받는 방식으로 옮겼습니다. 외부는 그대로 두고 내부만 바꾼 것인데, 두 방식을 섞어 쓰는 일이 드물지 않습니다.
흔한 오해
JSON 을 주고받으면 REST 라고 보는 경우가 가장 많습니다. 실무에서 마주치는 REST 창구가 거의 다 JSON 을 쓰니 둘이 같은 말처럼 들립니다. 하지만 형식은 이 방식이 정하지 않습니다. /getDocument 라는 주소에 POST 로 요청을 보내고 JSON 을 받아도 REST 가 아니고, 주소에 자원 이름을 쓰고 동작을 나눠 쓰면 형식이 JSON 이 아니어도 REST 입니다. 판단 기준은 주소와 동작이 갈라져 있는지입니다. 이걸 섞어 이해한 팀은 주소를 동사로 짓고서 REST API 라고 부르고, 쓰는 쪽은 결국 창구 목록을 다 읽게 됩니다.
낡은 방식이라고 보는 시각도 자주 나옵니다. 더 새로운 방식들이 나왔고 각각 이 방식의 약점을 겨냥하고 있으니 그렇게 들립니다. 하지만 새 방식이 해결하는 문제는 좁습니다. 호출 횟수가 문제인 앱, 초당 수천 번이 문제인 서비스 사이 통신처럼 조건이 붙습니다. 조건에 해당하지 않는 창구에서는 규칙이 널리 알려져 있다는 점이 다른 모든 장점보다 큽니다. 새 방식으로 옮긴 팀이 반년 뒤에 겪는 문제는 대개 같습니다. 붙이는 쪽에 알려 줄 것이 늘고, 캐시를 다시 설계해야 하고, 그 방식을 아는 사람이 적습니다.
자주 헷갈리는 용어
| 용어 | 무엇을 기준으로 부르는가 | REST 와의 차이 |
|---|---|---|
| GraphQL | 부르는 쪽이 적어 보낸 항목 목록 | 주소가 하나이고 필요한 항목을 요청에 적습니다. 호출 횟수와 받는 양이 줄지만, 여는 쪽이 준비할 것과 중간 저장 설계가 늘어납니다 |
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16