
목 차
1. REST란 무엇인가?
2. RESTful과 RESTful API의 개념과 원칙
3. RESTful API의 구조적 특징과 예시
4. RESTful API의 장단점
5. GraphQL이란 무엇인가?
6. RESTful API vs GraphQL 비교
7. RESTful → GraphQL 전환 시 고려사항

REST는 Representational State Transfer의 약자로
네트워크를 통해 컴퓨터들끼리 통신할 수 있게 해주는 웹 아키텍처 스타일입니다.
웹의 본질인 자원(Resource)을 URL로 명확히 표현하고,
그 자원을 HTTP 메서드(GET, POST, PUT, PATCH, DELETE 등)를 활용하여
자원을 '상태적'으로 처리할 수 있도록 정의된 아키텍쳐 설계 원칙입니다.
즉, REST는 웹 서비스 설계를 위한 철학 또는 원칙이라고 할 수 있습니다.
REST는 ‘API는 이렇게 설계해야 해!’라는 규칙이 아니라,
로이 필딩(REST의 아버지)이 당시 HTTP 사용의 혼란을 정리하려 제안한 아키텍처 스타일에 가깝습니다.
| 제약 조건 | 설명 |
|---|---|
| Client-Server | 클라이언트와 서버는 명확히 분리되어야 함 |
| Stateless | 서버는 요청 간 클라이언트 상태를 저장하지 않음 |
| Cacheable | 응답은 캐시가 가능해야 함 |
| Uniform Interface | URI 및 HTTP 메서드의 일관된 인터페이스 유지 |
| Layered System | 클라이언트는 중간 서버 존재를 인식하지 않음 |
| Code on Demand (선택사항) | 서버는 클라이언트로 코드(JavaScript 등)를 전송 가능 |
클라이언트(프론트) 와 서버(백엔드)는 역할을 분리하고,
서로 독립적으로 개발 / 운영할 수 있어야 합니다.
서버는 요청 간의 상태를 저장하지 않고, 매 요청은 독립적이어야 합니다.
응답은 캐시 가능해야 하며, 캐시 여부를 명확히 지정할 수 있어야 합니다.
일관된 URI, 메서드, 표현 방식 등으로 인터페이스가 단순하고 일관돼야 합니다.
클라이언트는 중간 서버(프록시, 로드밸런서 등)의 존재를 알지 못한 채 요청해야 합니다.
클라이언트는 서버로부터 코드(JS 등)를 다운 받아 실행할 수 있어야 합니다.

REST 원칙을 엄격하게 지켜서 만든 API 입니다. ( == RESTful하게 만든 API )
'자원을 중심'으로 설계하고, ' HTTP 메서드와 상태코드 ' 를 활용해
'명확하고 일관된 방식'으로 클라이언트와 통신합니다.
즉 !, 클라이언트는 "무엇을" 요청하는지를 URL로 표현하고,
"어떻게" 요청할지를 HTTP 메서드로 구분하여 요청합니다.
이를 통해 API는 '예측 가능하고 일관적인 설계'를 가지며, 유지보수나 확장에 강해집니다.
| HTTP 메서드 | 의미 | 예시 |
|---|---|---|
| GET | 리소스 조회 | GET /users |
| POST | 리소스 생성 | POST /users |
| PUT | 리소스 전체 수정 | PUT /users/1 |
| PATCH | 리소스 부분 수정 | PATCH /users/1 |
| DELETE | 리소스 삭제 | DELETE /users/1 |
REST API
RESTful API와 혼용해서 많이 쓰이는데, 엄밀히 따지면 두가지는 다릅니다.
- REST API는 REST를 참고해 만든 API (느슨한 개념)이고,
- RESTful API는 REST 원칙을 엄격하게 지켜서 만든 API 입니다.
역할과 사용 예시를 중심으로 더 자세히 !
GET
GET /users/123 (특정 사용자 조회)
GET /users?page=2&limit=10 (페이지네이션된 목록 조회)
POST
POST /users
Body: { "name": "경일", "email": "k@ex.com" }
PUT
PUT /users/123
Body: { "name": "경일", "email": "k@ex.com" }
PATCH
PATCH /users/123
Body: { "email": "new@ex.com" }
DELETE
DELETE /users/123 (id=123 사용자 삭제)
HTTP 메서드를 적절히 설정해, API를 구성하는 것만으로는 충분하지 않습니다.
API 응답에는 성공 또는 실패 여부를 명확히 전달하는 상태코드가 함께 포함되어야 합니다.
'상태코드'는 클라이언트가 '응답을 해석하고,
그에 맞는 처리를 수행할 수 있게 도와주는 소통 수단'으로, RESTful 설계에서 매우 중요한 요소입니다.

위 표에서 의미는 공통적인 것으로 작성됐지만,
실제 명세서에는 각 상황에 맞춰, 설명을 자세하게 작성해야합니다.

URI는 리소스를 나타냄: /users, /users/1/posts
HTTP 메서드로 동작 정의
상태 코드를 활용한 명확한 응답 처리
HATEOAS 지원 가능 (선택사항): 응답에 관련 링크 포함
GET /products/100
HTTP/1.1 200 OK
{
"id": 100,
"name": "Wireless Mouse",
"price": 29.99
}

| 구분 | 설명 |
|---|---|
| 표준화된 설계 | HTTP 메서드, 상태코드 등 글로벌 규약 활용 |
| 직관적 구조 | URI만 보아도 자원과 행위를 유추 가능 |
| 캐싱 가능 | HTTP 프로토콜 기반으로 GET 요청 캐싱 용이 |
| 툴 호환성 | Swagger, Postman, OpenAPI 등과 높은 호환성 |
| 클라이언트/서버 분리 | 프론트와 백엔드가 독립적으로 개발 가능 |
| 구분 | 설명 |
|---|---|
| 오버페칭/언더페칭 문제 | 필요한 데이터보다 많거나 적게 받을 수 있음 |
| 엔드포인트 증가 | 복잡한 관계형 데이터일수록 URI가 폭발적으로 증가 |
| 버전 관리 복잡성 | /v1/, /v2/ 등 엔드포인트 버저닝 필요 |
| 관계형 쿼리 어려움 | 다중 자원 fetch 또는 nested 관계 표현이 제한적 |
| 일관성 관리 어려움 | 대형 API에서는 URI/동작 규칙 일관성 유지가 어렵다 |

RESTful API는 만능일까? 왜 다 이것만 찬양할까요?
이유는 비교적 단순합니다. 웹 초창기부터 표준으로 자리 잡았고,
오랜 시간 동안 큰 문제 없이 사용되며 안정적인 생태계가 구축됐기 때문입니다.
즉, “큰 문제없이 오랫동안 잘 사용함” 이 가장 큰 이유!
하지만 시간이 흐르며 새로운 요구와 상황이 생기면서,
RESTful API가 항상 최적은 아니라는 고민도 이어졌습니다.
| 상황 | 문제점 |
|---|---|
| 클라이언트 화면 단위로 여러 데이터 조합이 필요할 때 | 다수의 요청으로 API 호출 비용 증가 |
| 모바일, 저속 네트워크 환경 | 오버페칭으로 데이터 낭비 발생 |
| 실시간 또는 부분 업데이트가 필요한 경우 | WebSocket, SSE 등 별도 구현 필요 |
| 자원이 관계형으로 깊이 얽혀 있을 때 | URI 설계와 패칭이 복잡해짐 |
API 추가해주세요 → 추가했어요 → 이것도 필요해요 → 추가했어요
명세 작성했어요 추가 부탁드려요 → 추가했어요 → 수정이 필요해요.
이처럼 서버와 클라이언트가 번갈아가며 API를 맞추는 과정이 반복됩니다.
개발 생산성은 점점 느려지고, 요구사항이 바뀔 때마다 코드 수정이 이어지며 비효율이 생깁니다.
그에 대한 대안 중 하나가 바로 GraphQL입니다.
비교적 최근인 2015년, 페이스북이 공개한 데이터 쿼리 언어로,
복잡한 데이터 구조를 더 유연하고 효율적으로 다루기 위해 등장했습니다.
RESTful의 구조적 한계를 보완하면서 다음과 같은 철학을 가집니다.
| 요소 | GraphQL 철학 |
|---|---|
| 요청 | 필요한 것만 명시적으로 요청 (정확성) |
| 응답 | 필요한 데이터만 반환 (최적화) |
| 확장성 | 자원 간 관계와 응답 구조를 유연하게 표현 |
| 표현력 | 쿼리, 뮤테이션, 서브스크립션 등 세분화된 역할 |
예를 들어, 클라이언트가 사용자 이름과 해당 사용자의 최근 게시글 제목만 필요할 경우,
다음과 같이 요청할 수 있습니다:
query {
user(id: "1") {
name
posts(limit: 3) {
title
}
}
}
이는 REST 방식에서는 GET /user/1 → GET /user/1/posts → 필터링 등의
여러 단계 요청이 필요했을 상황을 단일 쿼리로 해결해 줍니다.
GraphQL은 이 과정이 오케스트라 같다고 비유합니다.
클라이언트는 쿼리를 통해 구인글, 지원자, 이력서 등 여러 데이터를
한 번에 선언적으로 요청할 수 있고, 서버는 그에 맞는 응답을 제공합니다.
이처럼 스키마를 중심으로 명확한 계약이 존재하기 때문에 오버페칭 없이
필요한 데이터만 가져올 수 있으며, 새로운 UI 요구에도 별도의 엔드포인트 없이
스키마 확장만으로 유연하게 대응할 수 있습니다.
이로 인해 네트워크 요청 횟수가 줄고,
초기 로딩 지연이나 레이아웃 쉬프트 없이 예측 가능하고 생산적인 협업이 가능해집니다.
ex) 당근마켓의 GraphQL 활용.

대답은 No,
GraphQL 역시 아래와 같은 '도입 비용 및 트레이드오프'가 존재합니다.
스키마 설계 및 학습 필요
복잡한 인증/인가 로직 구현 난이도 증가
필드 단위 쿼리 로깅 및 모니터링 어려움
캐싱, CDN 적용이 REST에 비해 복잡
REST와 GraphQL은 각자 사용 목적이 다릅니다.
따라서 프로젝트의 요구사항, 트래픽 성격, 도메인 복잡도에 따라서
다음처럼 선택 또는 병행 적용할 수 있습니다.
| 상황 | 권장 선택 |
|---|---|
| 단순 CRUD API, 명확한 리소스 중심 | ✅ RESTful API |
| 화면 단위로 다양한 조합의 데이터 필요 | ✅ GraphQL |
| 하이브리드 백엔드, 마이크로서비스 | ✅ REST + GraphQL 혼합 설계 |

GraphQL은 클라이언트가 필요한 데이터만 선언적으로 요청할 수 있는
Query Language for API입니다.
REST가 리소스 중심이라면, GraphQL은 쿼리 중심으로 동작합니다.
| 항목 | 설명 |
|---|---|
| 단일 엔드포인트 | 모든 요청은 /graphql 하나로 처리 |
| 정형화된 Schema | 타입, 쿼리, 뮤테이션 등을 명시적으로 정의 |
| 필드 단위 요청 | 원하는 데이터만 정확히 요청 가능 |
| 실시간 기능 지원 | Subscription을 통해 WebSocket 기반 실시간 데이터 전송 가능 |
| 타입 안전성 | Schema 기반 정적 타입 검사 가능 |
query {
user(id: "1") {
name
posts {
title
}
}
}
이 요청은 /graphql 하나로 유저 정보 + 해당 유저의 게시글 리스트를 한 번에 받을 수 있습니다.

| 항목 | RESTful API | GraphQL |
|---|---|---|
| 엔드포인트 구조 | 다수의 엔드포인트 (리소스별) | 단일 엔드포인트 (/graphql) |
| 데이터 요청 방식 | 고정된 응답 구조 | 원하는 데이터 구조 정의 가능 |
| Over/Under Fetching | 빈번하게 발생 | 해결 가능 (정확한 필드 요청) |
| 버전 관리 | 엔드포인트 URI로 관리 | 타입 변경 및 Deprecation 활용 |
| 응답 효율 | 단순 요청은 효율적 | 복잡 요청도 1쿼리로 해결 가능 |
| 관계형 데이터 | 여러 요청 필요 (N+1 가능성 높음) | Nested 요청 자연스럽게 처리 |
| 도구 | Swagger, Postman | GraphQL Playground, Apollo Studio |
| 학습 곡선 | 낮음 | 스키마 설계, 툴 사용 등 진입 장벽 존재 |
| 보안 | 메서드 단위 인증 구조 명확 | 필드 단위 보안 정책 필요 |

RESTful API는 '정형화된 리소스를 단순하게 주고받는 구조'에 적합합니다.
반면에, GraphQL은 ' 관계형 데이터가 복잡하게 얽혀 있거나, 화면마다 필요한 데이터 구조가 다르며, 클라이언트 주도 하에 유연한 요청이 필요한 서비스에 적합합니다.

GraphQL은 타입 중심 아키텍처이므로, 도메인 모델을 정형화하여 설계
REST는 URI 단위로 제어 가능.
GraphQL은 필드 단위 보안이 필요
→ @auth, @role 디렉티브 또는 Resolver에서 처리
HTTP 캐싱 불가 → Apollo Client, Relay 등의 캐시 계층 활용.
CDN 캐싱은 어렵지만, Resolver-level 캐싱 또는 persisted query 적용 가능.
GraphQL은 단일 엔드포인트이므로, 요청 로그의 가시성 저하 가능.
쿼리 파싱, 리졸버 단위 로깅, 오픈소스 모니터링 도구 연동 필요.
REST는 Swagger 등 활용.
GraphQL은 Playground, GraphiQL, Apollo Studio로 문서 자동 생성.
전체 API를 일괄 마이그레이션하기보다는, 일부 쿼리를 GraphQL로 먼저 래핑.
GraphQL + REST Hybrid 구조를 도입하여 리스크 완화 가능.
