1. RESTful 기본 개념
RESTful은 HTTP 기반의 웹 서비스 설계 방식으로, 자원(Resource)에 대한 일관된 접근 방식을 제공합니다. REST(Representational State Transfer) 원칙을 따르며, 주로 클라이언트-서버 간 상호작용을 효율적이고 확장성 있게 설계하기 위해 사용됩니다.
RESTful 아키텍처의 주요 원칙
- 자원(Resource) 식별 : 각 자원은 URI(Uniform Resource Identifier)를 통해 고유하게 식별됩니다. 예를 들어, 사용자 정보를 나타내는 자원은
/users
로 표현하고, 특정 사용자의 정보를 가져올 때는/users/{userId}
와 같은 URI 구조를 사용합니다. - 무상태성(Statelessness) : 각 요청은 독립적이고, 서버는 클라이언트의 상태를 유지하지 않습니다. 즉, 클라이언트는 요청할 때마다 필요한 모든 정보를 포함해야 하며, 서버는 요청을 받을 때마다 필요한 데이터를 자체적으로 처리합니다.
- 일관된 인터페이스(Uniform Interface) : 자원에 접근하는 방식이 일관되어야 하며, 클라이언트는 요청 URI와 HTTP 메서드(GET, POST, PUT, DELETE)를 통해 자원에 접근하고 작업을 수행할 수 있습니다.
- 계층화(Layered System) : 시스템은 여러 계층으로 나눌 수 있으며, 클라이언트는 중간 서버의 존재를 알 필요 없이 요청을 전송할 수 있습니다. 이러한 계층 구조는 시스템 확장성을 높이는 데 도움이 됩니다.
RESTful APIs를 만들어야 하는 이유
- RESTful API를 개발하는 가장 큰 이유는 클라이언트 측을 특정 플랫폼에 제한하지 않고, 모바일, PC, 애플리케이션 등 다양한 플랫폼에서 사용할 수 있도록 하기 위함입니다.
- 과거에는 서버 측에서 데이터를 전달해주는 클라이언트 프로그램의 대상이 주로 PC 브라우저로 명확히 정해져 있었습니다. 그 당시에는 JSP, ASP, PHP 등을 이용한 웹 페이지를 구성하고 작업을 진행하면 되었습니다.
- 그러나 스마트 기기들이 등장하면서 TV, 스마트폰, 태블릿 등 클라이언트 프로그램이 다양화되었고, 그에 맞춰 서버를 일일이 만드는 것은 비효율적이 되었습니다.
- 이런 상황에서 개발자들은 클라이언트 측을 전혀 고려하지 않고, 메시지 기반 통신과 XML, JSON과 같은 클라이언트에서 바로 객체로 변환 가능한 형태의 데이터 통신을 지향하게 되었고, 그 결과 서버와 클라이언트의 역할을 분리하게 되었습니다.
2. 주요 기능과 특징
2.1 URI와 자원 접근 방식 RESTful 설계에서는 자원을 식별하는 URI가 중요합니다. 각 자원을 고유한 URI로 관리하고, 이를 통해 자원에 접근합니다. 예를 들어 /products
는 상품 리스트를, /products/{productId}
는 특정 상품에 대한 정보를 나타냅니다. 이러한 일관된 자원 경로는 클라이언트가 RESTful API를 예측 가능하게 사용할 수 있게 해줍니다.
2.2 HTTP 메서드의 명확한 역할 HTTP 메서드의 의미에 따라 자원에 대한 작업을 구분합니다
이름 | 조작 | SQL |
CREATE | 생성 | INSERT |
READ(or RETRIEVE) | 읽기(또는 인출) | SELECT |
UPDATE | 갱신 | UPDATE |
DELETE(or DESTROY) | 삭제(또는 파괴) | DELETE |
- GET : 자원 조회
- POST : 자원 생성
- PUT/PATCH : 자원 수정
- DELETE : 자원 삭제
RESTful 아키텍처는 이 메서드들로 CRUD 작업을 처리하여 직관적이고 효율적인 서비스 설계를 돕습니다.
2.3 무상태성의 이점
RESTful은 무상태성을 원칙으로 삼아, 서버가 클라이언트의 상태를 유지하지 않습니다. 이는 각 요청이 독립적으로 처리되며, 서버 확장 시 다른 서버로 요청이 분배되기 쉽다는 점에서 높은 확장성을 제공합니다. 또한 서버 재시작이나 장애 복구에 유리합니다.
2.4 캐싱을 통한 성능 최적화
자주 요청되는 자원에 대해서는 캐싱을 적용할 수 있습니다. 이를 통해 서버의 부하를 줄이고 응답 시간을 단축하여 사용자 경험을 개선할 수 있습니다. 캐싱은 HTTP 응답 헤더(Cache-Control
, ETag
등)를 사용해 설정합니다.
2.5 HATEOAS
RESTful API에서는 HATEOAS(Hypermedia as the Engine of Application State)를 통해 API 응답에 관련된 다른 URI 링크를 포함할 수 있습니다. 이를 통해 클라이언트는 응답 데이터를 통해 자동으로 관련된 자원에 접근할 수 있습니다. 예를 들어, 사용자 정보를 반환할 때 사용자의 주문 목록으로 가는 링크를 함께 제공하면, 클라이언트는 추가 정보를 손쉽게 얻을 수 있습니다.
2.6 Self-descriptive Messages (자기 설명적 메시지)
RESTful에서는 요청과 응답 자체가 그 목적과 구조를 설명할 수 있도록 설계됩니다. 이를 통해 서버는 클라이언트로부터 온 요청의 목적을 쉽게 파악할 수 있으며, 응답도 클라이언트가 이해할 수 있게 설계됩니다. 예를 들어, HTTP 헤더에 Content-Type
을 명시하여 데이터 형식을 나타내는 것이 좋은 사례입니다.
2.7 필드 필터링 (Field Filtering)
RESTful API에서는 필요한 정보만 응답에 포함하도록 필터링 기능을 제공하기도 합니다. 예를 들어 /users?fields=name,email
처럼 필요한 필드를 쿼리로 요청하면, 서버는 해당 필드만 포함한 데이터를 응답해 네트워크 효율을 높일 수 있습니다.
2.8 버전 관리
RESTful API는 보통 URI에 버전을 포함해 v1
, v2
와 같은 버전 관리 방식을 사용합니다. 이렇게 하면 API가 변경되거나 새로운 기능이 추가될 때도 이전 버전을 사용하는 클라이언트가 영향을 받지 않도록 설계할 수 있어, API의 지속적인 확장이 가능합니다.
3. RESTful 세부 규칙
1. 슬래시 구분자 ( / ) : 계층 관계
2. URI 마지막 문자로 슬래시 ( / )를 포함하지 않는다.
- 즉 URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것
- 역으로 리소스가 다르면 URI도 달라져야 한다.
3. 하이픈 ( - ) : URI 가독성을 높이는데 사용
4. 밑줄 ( _ ) : URI에 사용하지 않음
5. URI 경로는 소문자 사용 & 대문자 사용은 지양함
6. 파일확장자는 URI에 포함하지 않는다.
- REST API 에서는 Message Body 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다.
- 대신 Accept Header 를 사용한다.
- ex)
GET
:http://restapi.exam.com/orders/2/Accept: image/jpg
7. 리소스 간에 연관 관계가 있는 경우
- /리소스명/리소스ID/관계가 있는 다른 리소스 명
- ex) GET: /users/2/orders (일반적으로 소유의 관계를 표현할 때 사용)
4. 데이터를 클라이언트에 반환하는 방법
RESTful API는 주로 JSON 형식을 통해 데이터를 반환합니다. JSON은 데이터 구조화가 쉬우며, 브라우저와 API 클라이언트가 모두 쉽게 처리할 수 있는 형식이기 때문에 많이 사용됩니다. 요청에 대한 결과는 HTTP 상태 코드와 함께 반환되어 클라이언트가 요청의 성공 여부를 파악할 수 있게 합니다.
- 예를 들어, 성공적인 요청은
200 OK
를, 요청 데이터가 잘못된 경우는400 Bad Request
, 권한이 없을 경우는401 Unauthorized
등의 상태 코드와 메시지를 함께 반환합니다.
■ HTTP 응답 코드
4.1 성공(Success)
상태코드 | 내용 |
200 | 정상적으로 수행 |
201 | 자원(Resource) 생성 요청에 대해 성공적으로 수행됨 |
4.2 클라이언트 에러(Client Error)
상태코드 | 내용 |
400 | 클라이언트 요청이 부적절할 경우 응답 코드 |
401 | 클라이언트가 권한이 없는 자원(Resource)를 요청하였을 때 응답 코드 |
403 | 보호되는 자원(Resource)를 요청하였을 때 응답 코드 |
405 | 클라이언트가 요청한 리소스에서는 사용 불가능한 Method를 이용했을 때 응답 코드 |
4.3 기타
상태코드 | 내용 |
301 | 클라이언트가 요청한 리소스에 대한 URL가 변경 되었을 때 응답 코드 |
500 | 서버에 뭔가 문제가 있을때 사용하는 응답 코드 |
5. RESTful 설계의 유의 사항
※ RESTful API 설계 시, 유의해야 될 사항들!!!
- URI 설계의 일관성 : 자원을 명확히 식별할 수 있는 URI를 사용해야 합니다. 예를 들어
/users/{userId}/orders
는 특정 사용자의 주문 정보를 반환하는 데 적합합니다. - HTTP 상태 코드 사용 : 각 응답에 HTTP 상태 코드를 명확히 설정하여, 클라이언트가 요청의 성공 여부를 파악할 수 있도록 합니다.
- 보안 : RESTful API는 주로 공개된 웹 환경에서 사용되므로 HTTPS를 통한 데이터 암호화와 JWT(JSON Web Token) 등을 활용한 인증 체계를 도입하는 것이 좋습니다.
- Rate Limiting (요청 제한) : RESTful API는 여러 클라이언트가 동시에 접근하는 경우가 많기 때문에, Rate Limiting 기능을 사용해 일정 시간 동안의 요청 횟수를 제한합니다. 이를 통해 서버 과부하를 방지하고 서비스의 안정성을 유지할 수 있습니다. 보통
429 Too Many Requests
상태 코드를 통해 요청 제한을 알리며, 재시도 시간도 함께 제공할 수 있습니다. - 페이징과 정렬(Pagination and Sorting) : RESTful API는 자원의 양이 많아질 수 있기 때문에, 대량의 데이터를 다룰 때 페이징(Paging) 기능을 지원해 필요한 범위의 데이터만 제공하는 것이 좋습니다. 보통
page
와size
쿼리 파라미터를 사용하여 클라이언트가 페이지 별로 데이터를 요청할 수 있도록 하며,sort
파라미터로 정렬 옵션을 지원하기도 합니다. - Error Handling (에러 처리) : RESTful API는 에러가 발생할 경우 클라이언트가 원인을 쉽게 파악할 수 있도록 표준화된 에러 응답 구조를 반환하는 것이 중요합니다. 보통 에러 응답에는
status
,message
,errorCode
등의 필드를 포함하여 에러 원인과 해결 방법을 명확히 알려줄 수 있습니다. - Documentation (API 문서화) : RESTful API는 명확한 문서를 제공하는 것이 필수입니다. OpenAPI (예: Swagger)와 같은 도구를 사용하여 API의 사용 방법, 요청 & 응답 구조, 파라미터 설명 등을 자동으로 문서화할 수 있으며, 이를 통해 개발자들이 쉽게 API를 이해하고 사용할 수 있습니다.
6. TIP & 정리
▶ RESTful 설계 시 권장 사항
RESTful 설계를 통해 확장 가능하고 유지보수하기 쉬운 API를 구축할 수 있지만, 이를 위해 URI 설계 규칙과 HTTP 메서드의 역할을 엄격히 지키는 것이 중요합니다. 또한, 자주 사용되는 자원에 대해 캐싱을 적용하고, 무상태성 원칙을 지켜 서비스의 확장성과 유연성을 높이는 것이 좋습니다.
▶ 정리
RESTful API는 HTTP 메서드를 통해 자원에 접근하고 관리하는 일관성 있고 확장성 높은 웹 서비스 설계 방식을 제공합니다. 자원 중심의 URI 설계와 무상태성 원칙을 통해 클라이언트와 서버 간 명확한 역할 분리가 가능해지고, 클라이언트가 API를 예측 가능하게 사용할 수 있습니다.
다음에는 OpenAPI (예: Swagger)와 같은 여러가지 도구들에 대해 알아보겠습니다.
'Spring' 카테고리의 다른 글
(Spring) 데이터베이스 개념 및 MySQL 개요 (0) | 2024.11.04 |
---|---|
(Spring) HTTP 데이터 객체 처리 및 CRUD 구현하기 (0) | 2024.10.30 |
(Spring) Path Variable & Request Param 차이점 (0) | 2024.10.29 |
(Spring) Jackson과 Spring에서의 활용 (0) | 2024.10.28 |
(Spring) 삭제 관련 Cascade 사용 여부에 따른 정리 (0) | 2024.10.24 |