ts-rest란?
ts-rest는 TypteScript 기반의 API Contract 를 중심으로 서버와 클라이언트 간의 타입 안정성을 보장하는 라이브러리
핵심 키워드
- Contract-first
- End-to-End Type Safety
- Framework-agnostic core
핵심 아이디어
API의 진짜 인터페이스는 Controller도 아니고, Client 함수도 아니라 하나의 Typescript Contract다
- API 요청/응답 구조
- HTTP method/path
- 상태 코드별 응답 타입
을 하나의 contract 객체로 선언하고, 해당 contract를
- 서버에서는 구현해야 할 스팩
- 클라이언트에서는 자동 생성되는 API 인터페이스
로 사용
기존 방식과 차이
| 기존 방식 | ts-rest |
|---|
| 서버 DTO 따로 | 단일 contract |
| 클라이언트 API 타입 수동 작성 | 자동 생성 |
| 타입은 컴파일 타임 전용 | 런타임 검증 포함 |
| 서버 변경시 프론트 깨짐 | 컴파일 단계에서 즉시 감지 |
왜 만들어졌을까?
공식 문서에서 지적하는 기존 API 개발의 근본적인 문제는 다음과 같다.
서버와 클라이언트의 타입의 불일치
- 서버는 DTO를 바꿨는데 클라이언트는 이전 타입을 사용
- 해당 문제가 런타임에서 발견됨
API 타입이 암묵적이다
보통 API는 Controller, Swagger 문서, 프론트 API 함수 세곳에 흩어져 정의된다.
ts-rest는 해당 정의가 오직 contract에서만 존재해야 한다는 철학을 가진다.
OpenAPI는 타입이 안전하지 않다
공식 문서에서 명확히 말하는 포인트는 다음과 같다.
- OpenAPI는 문서 생성 도구
- Typescript 타입 시스템과 직접 연결되지 않음
- 코드 변경과 문서 불일치가 자주 발생
ts-rest는 Typescript 자체를 스펙 언어로 사용
ts-rest의 Contract란 무엇인가?
Contract란 “계약”이라는 의미로 다음과 같은 API 문서를 하나의 계약으로 정의하고 정적으로 선언한 객체다.
1{
2 method: 'GET' | 'POST' | ...
3 path: '/users/:id'
4 body?: Schema
5 query?: Schema
6 headers?: Schema
7 responses: {
8 200: Schema
9 404?: Schema
10 }
11}
해당 Contract는 다음 용도로 사용된다.
- 서버에서는 반드시 구현해야할 인터페이스
- 클라이언트에서는 호출 가능한 함수 시크니처
따라서, ts-rest에서 Contract는 타입+런타임 스펙이다.