쉽게 말하면, REST 원칙에 따라 API를 설계한다는 건 “서버가 제공하는 기능을 URL에 동사처럼 적는 게 아니라, 자원(Resource)을 중심으로 표현하고 HTTP의 규칙을 의미에 맞게 사용하라”는 뜻이야.
예를 들어 수강신청 시스템을 만든다고 해보자.
이렇게 만들 수도 있지:
POST /getStudents
POST /createCourse
POST /cancelEnrollment
POST /getMySchedule
동작은 할 수 있어. 하지만 REST스럽지는 않아. URL에 get, create, cancel 같은 행동 이름이 들어가 있기 때문이야.
REST에서는 먼저 “우리 시스템의 자원이 뭐지?”를 생각해.
학생(Student)
강좌(Course)
수강신청(Enrollment)
시간표(Schedule)
그리고 URL은 보통 명사로 표현해.
/students
/courses
/enrollments
그다음 “무슨 행동을 하는가?”는 HTTP Method로 표현해.
예를 들어:
GET /courses
→ 강좌 목록 조회
GET /courses/123
→ 123번 강좌 조회
POST /enrollments
→ 수강신청 생성
DELETE /enrollments/456
→ 456번 수강신청 취소
이런 식이야.
핵심은 대략 네 가지 정도로 이해하면 돼.
1. URL은 자원을 표현한다
URL에는 가능하면 행동보다는 대상을 적는다.
안 좋은 예:
POST /registerCourse
REST스럽게 하면:
POST /enrollments
왜냐하면 “수강신청”이라는 자원을 하나 새로 만든다고 보는 거야.
2. 행동은 HTTP Method로 표현한다
대표적으로:
GET
→ 조회
POST
→ 생성
PUT / PATCH
→ 수정
DELETE
→ 삭제
예를 들어:
GET /students/10
은 학생 조회,
DELETE /enrollments/100
은 수강신청 삭제.
그래서 REST에서는:
URL = 무엇을 대상으로 하는가
HTTP Method = 무엇을 할 것인가
로 나눠서 생각해.
3. 서버는 요청 사이의 클라이언트 상태를 과도하게 기억하지 않는다
REST의 중요한 특성 중 하나가 Stateless야.
예를 들어 클라이언트가:
POST /enrollments
를 보냈다면 서버는 그 요청 하나만 보고 처리하는 데 필요한 정보가 충분해야 해.
대략:
{
"studentId": 10,
"courseId": 30
}
같이.
서버가:
“아까 네가 어떤 학생을 선택했었지?”
같은 이전 요청의 임시 상태에 의존하도록 설계하지 않는 게 REST의 기본 방향이야.
물론 인증 토큰이나 DB의 학생 정보까지 없애라는 뜻은 아니야.
핵심은:
각 HTTP 요청이 가능한 한 독립적으로 해석 가능해야 한다.
는 거야.
4. 결과를 HTTP Status Code로 의미 있게 표현한다
예를 들어 수강신청 성공이면:
201 Created
학생이 없으면:
404 Not Found
시간표가 겹치거나 18학점을 초과해서 신청할 수 없다면 설계에 따라:
409 Conflict
같은 응답을 줄 수 있어.
서버 내부에서 실패했다고 무조건:
200 OK
{
"success": false
}
만 보내는 것보다 HTTP가 이미 가지고 있는 의미를 활용하는 게 REST 설계에 더 가깝지.
예를 들어 수강신청 API를 REST스럽게 만든다면 이런 느낌이야.
GET /students/10
학생 10 조회
GET /courses
강좌 목록 조회
GET /courses/30
30번 강좌 조회
POST /enrollments
Body:
{
"studentId": 10,
"courseId": 30
}
수강신청 생성
DELETE /enrollments/123
123번 수강신청 취소
GET /students/10/enrollments
10번 학생의 수강신청 목록 조회
또는:
GET /students/10/schedule
처럼 시간표를 표현할 수도 있어.
그리고 REST를 이해할 때 많이 헷갈리는 게 하나 있어.
REST API = JSON을 쓰는 API는 아니야.
JSON은 그냥 데이터 표현 방식일 뿐이고:
REST
→ API 구조와 통신 방식에 대한 설계 스타일
JSON
→ 데이터를 표현하는 형식
이야.
또:
HTTP 사용
= 무조건 REST
도 아니야.
예를 들어:
POST /doAttack
POST /movePlayer
POST /getPlayer
처럼 HTTP는 쓰지만 모든 행동을 RPC처럼 설계할 수도 있어.
면접에서 “REST 원칙에 따라 API를 설계했습니다”라고 했다면 보통 최소한 이런 의미를 기대해.
“리소스를 중심으로 URL을 설계하고, 조회/생성/수정/삭제를 HTTP Method로 구분했으며, 요청 간 상태 의존성을 최소화하고, 결과를 적절한 HTTP Status Code로 표현했습니다.”
초보자 관점에서 제일 짧게 기억하면:
REST = URL에는 ‘무엇’을 적고, HTTP Method에는 ‘무엇을 할지’를 적는 방식.
HTTP
= 통신 규칙
REST
= HTTP를 활용해서 API를 구조화하는 설계 원칙
게임으로 비유하면 HTTP는 네트워크 패킷 규격에 가깝고, REST는 그 규격 위에서:
이 패킷은 조회
이 패킷은 생성
이 URL은 Course라는 자원
같은 의미 체계를 어떻게 잡을지 결정하는 방식이야.
그리고 실제로 C#에서 ASP.NET Core 같은 프레임워크를 쓰면 보통 네가 HTTP 문자열을 직접 파싱하지 않아.
예를 들어:
[HttpGet("/courses/{id}")]
public Course GetCourse(int id)
{
...
}
라고 작성하면 프레임워크가 내부적으로 HTTP 요청을 읽고:
GET /courses/10
을 해당 메서드에 연결해줘.
그래서 개발자는 HTTP 프로토콜의 모든 바이트를 직접 구현하기보다, 이미 구현된 HTTP 서버 기능 위에서 API의 의미와 규칙을 설계하는 경우가 대부분이야.
한 문장으로 정리하면:
HTTP는 이미 정해진 통신 프로토콜이고, REST API를 만든다는 것은 그 HTTP 프로토콜을 따르면서 Resource, Method, Status Code 같은 요소를 REST 원칙에 맞게 설계하는 것이다.