웹서비스를 개발할 때 늘 사용하는 REST API에 대해 알아보자
그리고 REST API를 어떻게 설계해야하는지
REST API의 버전을 어떻게 관리해야하는지 정리해보고자 한다.
API란?
Application Programming Interface 애플리케이션 프로그래밍 인터페이스의 약자이다.
여기서 인터페이스는 장치라는 뜻으로 애플리케이션끼리의 통신을 도와주는 중개자 역할을 한다.
즉, 많이들 말하는 API 문서란
어떻게 요청을 하고 어떤 형식으로 응답을 할지, 통신을 어떻게 주고 받을지
약속이 적힌 문서와도 같다.
이러한 통신규약 역할을 하는 API는 REST API뿐아니라 GraphQL, gRPC 등 다양한 종류를 가지고 있다.
그렇다면 REST API의 특징은 무엇일까?
REST API는 Representational State Transfer의 약자로 restful한 API라고도 한다.
"restful하다는 것은 restful 원칙에 부합하다는 것"을 뜻한다.
restful 원칙에 부합한 인터페이스가 REST API인 것이다.
restful원칙이란?
1. Uniform Interface 균일한 인터페이스
아래와 같은 특징을 가진 인터페이스여야 한다.
- 각 자원은 고유한 식별자를 가져야한다.
- 인터페이스는 클라이언트와 서버간에 상호작용에 관련된 각 리소스를 고유하게 식별해야한다.
- 예) http URI --식별가능-->고유한 주소로 보내겠다 , application/json --식별가능--> json으로 보내겠다
- 표현을 통한 상태 전달
- 리소스는 서버 응답에 균일한 표현을 가져야한다.
- 예) 서버 응답 상태코드, 미디어 타입 content-type ..
- 자체 설명 메시지
- 각 리소스 표현에는 메시지 처리 방법을 설명하는데 충분한 정보가 포함되어야한다. 설명 필요없이 자체만으로도 어떻게 처리해야되는지 이해가 되어야한다.
- 예) GET, POST,, JSON 어떻게 처리할지
- 애플리케이션 상태의 엔진으로서의 하이퍼미디어
- 클라이언트는 애플리케이션의 초기 URI만 가지고 있어야한다. 클라이언트 애플리케이션은 해당 url을 사용해 다른 모든 리소스와 상호작용을 한다.
2. 클라이언트 - 서버 통신
클라이언트와 서버 통신 구조를 가진다.
3. 무상태
http프로토콜을 기반으로 하는 rest api는 http의 특성을 그대로 물려받았다.
그리하여 무상태 특징을 가진다.
무상태란, 서버가 클라이언트의 이전 상태를 저장하지 않고 독립적으로 처리되어야함을 뜻한다.
http 요청은 독립적이어서 이전 요청과 상태정보를 공유하지 않는다.
4. 캐시를 사용할 수 있다.
http를 사용하기 때문에 http의 캐시 저장 기능을 사용할 수 있다.
무상태 특징으로 이전 요청에 대해 상태를 공유하지 않는다.
그 결과, 동일 요청에 대한 응답이 일관적이다!
특정 url을 가지고 이전에 어떤 요청을 했든 상관없이 동일 요청 동일 url에 대한 응답이 같기 때문에
응답데이터를 캐시로 저장하고 사용하기 좋다.
5. 계층화 Layered System
요청과 응답이 분리되어 계층화된 레이어로 시스템을 구성할 수 있다. 예로 MVC 패턴이 있다.
http프로토클을 기반으로 하는 REST API는
표준 HTTP 메서드(GET, POST, PUT, DELETE..)와 URI(Uniform Resource Identifiers)를 사용하여 리소스를 식별한다.
결론적으로
REST API는
클라이언트와 서버의 통신에 있어
리소스를 알아보기 쉽게 표현한, 통일된 인터페이스를 구성하는 것을 목적으로 한다.
REST는 크게 다음과 같이 구성되어있다.
- 자원 : HTTP URL
- 자원에 대한 행위: HTTP Method
- 자원에 대한 표현: Representation
REST API 설계 규칙을 알아보자
1. 엔드포인트에 동사 대신 명사를 사용한다.
HTTP 요청 메서드에 이미 동사가 있기 때문이다.
만약 개발자가 선택적으로 동사를 넣는다면 불필요하게 길어지기만 할 뿐이다.
작업은 HTTP 요청 메서드로 표시되어야한다.
- GET 리소스 검색한다
- POST 새 데이터를 서버에 제출한다
- PUT 기존 데이터를 업데이트한다
- DELETE 데이터를 제거한다
동사는 다음처럼 CRUD 작업에 매핑된다
만약 쇼핑몰에서 옷을 가져온다면
다음과 같은 'HTTP 메서드 작업 + 경로' 로 이루어진다.
GET /articles/
새 기사를 추가한다면
POST /articles/:id
기존 기사를 삭제한다면
DELETE /articles/:id
이처럼 경로 자체에는 동사가 없어야한다.
2. 엔드포인트에 논리적 중첩을 사용한다
엔드포인트를 디자인할 때 관련 정보가 포함된 엔드포인트를 그룹화하는 것이 좋다.
한 개체가 다른 개체를 포함할 수 있는 경우 이를 반영해 디자인할 수 있다.
실제 데이터베이스에 어떻게 구성되어있는지와 상관없이 설정해주면 좋다.
오히려 엔드포인트에서 데이터베이스 구조를 그대로 가져오는 것이 좋지 않다.
각 기사에 대해 고유한 댓글이 있을 때 이 댓글을 가져올 때
/articles/:articleId/comments
경로로 묶어줄 수 있다.
하지만 중첩이 너무 심하지 않게 아예 새로운 경로로 만들어주는 방법도 고려해야한다.
예로 댓글에 대한 작성자를
"/users/:userId" 로 만들 수도 있다.
3. 표준 오류 코드를 적절히 반환한다.
API를 통해 오류가 발생했을 때 이에 적절히 대처할 수 있도록
HTTP 상태코드로 오류 코드를 반환해야한다.
4. 데이터 필터링이 필요하다. (필터링, 정렬, 페이지 매김)
코드를 API를 이용해 한번에 너무 많은 데이터를 반환하려고 하면 안된다.
따라서 항목을 필터링하는 방법이 필요하다.
쿼리 문자열을 이용해 정렬할 필드를 지정할 수도 있고 url을 통해 쿼리 문자열을 추출할 수도 있다.
5. 보안을 유지해야한다.
API를 통해 클라이언트와 서버가 통신하는 동안, 중요한 데이터가 유실될 수도 있다.
이를 막기 위해 디지털 인증서 " SSL 보안소켓 계층, TLS 전송계층보안"를 사용한
HTTPS 프로토콜이 있다.
6. REST API Versioning 버전관리 전략을 사용한다.
운영중인 서비스의 API를 업데이트하는 경우 API versioning 전략이 필수적이다.
클라이언트는 기존 REST API를 계속 사용하다 준비가 되면 최신 API로 마이그레이션 할 수 있다.
1) 엔드포인트 경로를 통한 버전 관리
http://www.example.com/v1
기본적으로 가장 많이 사용한다 API 시작부분에 /v1, /v2 등을 추가한다. 직관적이고 간단하다는 장점이 있다.
2) 쿼리 매개변수를 통한 버전관리
http://www.example.com/product?version=1
3) 사용자 정의 헤더를 통한 버전관리
curl -H "Accepts -version:1.0"
맞춤헤더가 필요하다.
하지만 버전관리로 url이 복잡해지지 않는다는 장점이 있다.
4) 콘텐츠 협상을 통한 버전관리
6. 슬래시 는 계층관계를 나타나는데 사용되며 url마지막에는 포함하지 않는다.
http://www.example.com/artlists/arts
7. _ 언더바는 사용하지 않고 - 하이픈을 사용한다.
8. 대문자 대신 소문자를 사용한다.
9. 파일 확장자는 URI에 포함하지 않는다.
출처:
https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/