
RESTful API는 REST 아키텍처 스타일을 기반으로 설계된 API(Application Programming Interface)로, 서버와 클라이언트 간의 통신을 표준화된 방식으로 제공하는 프로토콜입니다. REST는 "Representational State Transfer"의 약자로, 자원을 이름(URI)으로 구분하고, 각 자원에 대한 행위는 HTTP 메서드로 정의하여 일관성 있고 쉽게 확장할 수 있는 웹 서비스를 설계하는 방법론을 제공합니다.
REST는 웹 상의 자원을 URI(Uniform Resource Identifier)로 표현하고, HTTP 프로토콜을 통해 CRUD(Create, Read, Update, Delete) 작업을 수행합니다. RESTful API는 이러한 REST의 원칙을 지키는 API로, 웹 애플리케이션에서 자원을 관리하고 조작하기 위한 일관된 방법을 제공합니다.
RESTful API에서는 각 자원에 대해 HTTP 메서드를 통해 행동을 정의합니다. 주요 메서드는 다음과 같습니다.
RESTful API 설계를 위해 따르는 6가지 제약 조건이 있습니다. 이를 지키면 시스템이 RESTful 하다고 볼 수 있으며, 각 조건을 준수할수록 확장성과 유지보수성이 향상됩니다.
클라이언트-서버 구조
클라이언트와 서버가 명확히 분리되어야 합니다. 클라이언트는 요청을 보내고 서버는 응답을 반환하며, 서로 독립적으로 개발될 수 있습니다. 이렇게 분리함으로써 클라이언트와 서버는 서로 독립적인 기능을 유지하고, 한쪽의 변경이 다른 쪽에 미치는 영향을 최소화할 수 있습니다.
예시: 프론트엔드 애플리케이션이 서버 API로부터 데이터를 받아와 화면에 표시하는 구조입니다. 클라이언트와 서버가 분리되면, 프론트엔드를 변경해도 서버 코드에 영향을 주지 않게 됩니다.
무상태성(Stateless)
각 요청은 독립적이며, 서버는 요청 간의 상태를 저장하지 않습니다. 즉, 클라이언트의 요청에 필요한 모든 정보는 요청에 포함되어야 하며, 서버는 이전 요청의 정보를 보관하지 않습니다. 이 원칙은 서버의 확장성을 높이는 데 도움이 됩니다.
예시: 사용자가 페이지를 넘길 때마다 페이지 번호와 같은 정보가 요청에 포함되어야 합니다. 클라이언트는 매 요청마다 필요한 정보를 제공하므로, 서버는 요청만 처리하고 상태를 유지하지 않아도 됩니다.
캐시 가능성(Cacheable)
RESTful API는 클라이언트가 응답을 캐시할 수 있도록 설계되어야 합니다. 서버는 응답이 캐시 가능한지 여부를 헤더에 명시하며, 캐싱을 통해 네트워크 요청 수를 줄이고 성능을 높일 수 있습니다. 응답의 Cache-Control 헤더를 통해 캐싱 여부와 캐시 유효 시간을 설정할 수 있습니다.
예시: 자주 변경되지 않는 데이터(예: 공지사항 목록)에는 Cache-Control: max-age=3600 같은 헤더를 설정해 캐시 가능하다고 명시할 수 있습니다. 클라이언트는 이 정보를 캐시에 저장하여 이후 요청 시 캐시 데이터를 사용하게 됩니다.
계층형 시스템(Layered System)
REST 시스템은 여러 계층으로 구성될 수 있으며, 클라이언트는 중간 계층의 존재를 알 필요가 없습니다. 프록시나 게이트웨이 같은 중간 계층을 활용해 보안, 로드 밸런싱 등을 처리할 수 있으며, 이러한 구조는 시스템의 확장성과 보안성을 높입니다.
예시: 클라이언트는 API 게이트웨이를 통해 요청을 보내고, 게이트웨이는 요청을 실제 서버로 전달하는 역할을 합니다. 이를 통해 서버를 직접 노출하지 않으면서 보안성과 확장성을 높일 수 있습니다.
인터페이스 일관성(Uniform Interface)
RESTful API는 인터페이스가 일관성을 유지해야 합니다. 즉, API는 예측 가능하고 일관성 있게 설계되어야 하며, 이 원칙을 통해 클라이언트와 서버의 개발을 독립적으로 할 수 있습니다. 인터페이스 일관성의 주요 요소는 다음과 같습니다.
/users(모든 사용자), /users/{id} (특정 사용자)GET /users/1(1번 사용자 조회), DELETE /users/1 (1번 사용자 삭제)코드 온 디맨드(Code on Demand) (선택 사항)
REST에서는 선택적으로 서버가 클라이언트에 코드(예: JavaScript)를 전송하여 클라이언트가 이를 실행할 수 있게 합니다. 이 조건은 필수는 아니지만, 필요한 경우 클라이언트의 기능을 확장하는 데 유용합니다.
예시: 웹페이지가 서버에서 JavaScript 코드를 다운로드 받아 실행하여 클라이언트에서 일부 동적 기능을 수행하도록 할 수 있습니다.
간단한 예시로, 도서 관리 시스템의 RESTful API를 설계해 보겠습니다. 이 시스템에서는 책(Book)과 저자(Author)와 관련된 자원을 관리할 수 있습니다.
/booksGET /books: 모든 책 목록 조회GET /books/{id}`: 특정 책 조회POST /books: 새 책 추가PUT /books/{id}: 특정 책 정보 수정DELETE /books/{id}: 특정 책 삭제/authorsGET /authors: 모든 저자 목록 조회GET /authors/{id}`: 특정 저자 조회POST /authors: 새 저자 추가PUT /authors/{id}: 특정 저자 정보 수정DELETE /authors/{id}: 특정 저자 삭제이렇게 RESTful API를 설계하면, 클라이언트는 일관성 있는 방식으로 데이터를 요청하고 조작할 수 있습니다. 예를 들어, 특정 책의 상세 정보를 조회하려면 GET /books/1 요청을 보내는 방식으로 데이터를 얻을 수 있습니다.