사이드 프로젝트에서 REST API(HTTP API)를 설계할때 도움이 됐던 내용들을 정리해보았습니다.
REST는 개념과 원리는 정해져있지만 구체적인 공식 가이드 없기 때문에 많은 사이트를 참조했고, 도움이 됐던 글들은 아래 참조 사이트에서 확인하실 수 있습니다.
이상학님의 개발 블로그를 가장 많이 참고하였습니다.
💡 참조 사이트
REST란? REST API란? RESTful이란?
RESTful API란?
REST 아키텍처를 훌륭하게 적용하기 위한 몇가지 디자인 팁
REST API 제대로 알고 사용하자
RESTful API 설계
REST API 관점에서 바라보는 HTTP 상태 코드
REST API 이해와 설계
1. REST API란?
1.1 REST API의 탄생
REST는 Representational State Transfer라는 용어의 약자로 2000년도에 로이 필딩 (Roy Fielding)의 박사학위 논문에서 최초로 소개되었다.
로이 필딩은 HTTP의 주요 저자 중 한 사람으로 그 당시 웹(HTTP) 설계의 우수성에 비해 제대로 사용되어지지 못하는 모습에 안타까워하며 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다고 한다.
1.2 REST API란
HTTP 통신에서 어떤 자원에 대한 CRUD 요청을 Resource와 Method로 표현하여 특정한 형태로 전달하는 방식
자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다. 즉, REST란 어떤 자원에 대해 CRUD(Create, Read, Update, Delete) 연산을 수행하기 위해 URI(Resource)로 요청을 보내는 것으로, Get, Post 등의 방식(Method)을 사용하여 요청을 보내며, 요청을 위한 자원은 특정한 형태(Representation of Resource)으로 표현된다.
더 자세한 내용은 REST API의 특징을 통해 알 수 있다.
1.3 HTTP와 REST의 관계
HTTP (HyperText Transfer Protocol)는 웹 환경에서 정보를 주고받기 위한 프로토콜이고, REST는 소프트웨어 아키텍처다.
REST는 소프트웨어 아키텍처(설계 지침, 원리 등등)고 REST에서 클라이언트-서버 간 통신 시 HTTP를 사용한 것이다.
REST에 반드시 HTTP가 필요한 것은 아니고, 다른 프로토콜을 이용할 수도 있다.
하지만 대부분의 REST는 HTTP를 이용하고 거의 필수다. 사용함에 있어서 필수적으로 변한 경우라고 한다.(사실상 표준)
REST를 이용해 API를 설계하려면 HTTP에 대해서 알고 있어야 한다.
1.4 Restful이란
REST의 기본 원칙을 성실히 지킨 서비스 디자인을 “RESTful 하다" 라고 한다.
2. Rest API의 특징
2.1 Uniform (유니폼 인터페이스)
Uniform Interface는 URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일을 말한다.
2.2 Stateless (무상태성)
REST는 무상태성 성격을 갖는다. 다시 말해 작업을 위한 상태정보를 따로 저장하고 관리하지 않는다. 세션 정보나 쿠키정보를 별도로 저장하고 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다. 때문에 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다.
2.3 Cacheable (캐시 가능)
REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹표준을 그대로 사용하기 때문에, 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하는 점이다.
따라서 HTTP가 가진 캐싱 기능이 적용 가능하고 HTTP 프로토콜 표준에서 사용하는 Last-Modified태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.
2.4 Self-descriptiveness (자체 표현 구조)
REST의 또 다른 큰 특징 중 하나는 REST API 메시지만 보고도 이를 쉽게 이해 할 수 있는 자체 표현 구조로 되어 있다.
2.5 Client - Server 구조
REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 된다.
2.6 계층형 구조
REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.
3. URL 설계 규칙
3.1 중심 규칙
REST에서 가장 중요한 규칙 두가지
- URI는 정보의 자원을 표현해야 한다.
- 자원에 대한 행위는 HTTP method(GET, POST, PUT, DELETE 등)으로 표현한다.
3.2 URI는 심플하고 직관적으로 만든다.
REST API를 URI만 보고도, 직관적으로 이해할 수 있어야 한다.
최대 2depth 정도로 간단하게 만드는 것이 좋다.
GET /users
GET /users/534
POST api/users
3.3 resource의 이름은 복수 명사를 사용해야 한다.
(X) GET /User
(O) GET /Users
3.4 행위는 URL에 포함하지 않는다.
DELETE, UPDATE 등의 행위는 HTTP methods를 이용하여 표현한다.
GET method와 show의 표현이 중복되기 때문에 아래와 같은 방식은 좋지 않다.
GET /users/show/1
GET이라는 Method로 충분하게 표현할 수 있다.
GET /users/1
3.5 마지막에 /를 포함하지 않는다.
(x) http://helloworld.com/users/ → (o)http://helloworld.com/users
3.6 _(underbar) 대신 -(dash)를 사용한다.
-(dash)의 사용도 자제하는 것이 좋다.
http://api.test.com/users/post_commnets → http://api.test.com/users/post-commnets
3.7 소문자를 사용한다.
http://api.test.com/users/postCommnets → http://api.test.com/users/post-commnets
3.8 파일 확장자는 URL에 포함시키지 않는다.
(x) http://api.test.com/photos/apple.jpg
4. 올바른 HTTP Method 사용 방법
4.1 POST, GET, PUT, DELETE 4가지 method는 반드시 제공한다.
4.2 일부를 수정할때는 put보다 patch를 사용하자.
PUT : 자원이 전체 교체될때 사용한다. 일부분만 바뀌더라도 전체 속성을 보내야한다.
PATCH : 자원의 일부분이 교체될때 사용한다. 전체를 보낼 필요 없이 변경된 속성만 보낸다.
4.3 OPTIONS를 이용해서 완성도 높은 API를 만든다.
현재 리소스가 응답 가능한 Method를 제공한다.
5. HTTP 상태코드
HTTP Status Code(상태 코드)는 HTTP 요청이 성공했는지 실패했는지 서버에서 알려주는 코드다.
클라이언트는 HTTP의 상태 코드를 확인하여 요청의 성공, 실패를 확인할 수 있다.
클라이언트는 자신의 요청이 어떻게 처리되었는지 알 수 있는 방법은 서버의 응답밖에 없으므로 자세하고 세분화된 정보를 보내는 것이 좋다.
5.1 의미에 맞는 HTTP Status Code를 리턴한다.
Status는 성공(200)인데 body 내용에는 실패에 관한 내용을 리턴하면 안된다.
5.2 HTTP Status Code만으로 상태 에러를 나타낸다.
Status Code만으로 상태를 표시할 수 있으므로 body와 중복해서 표시할 필요 없다.
(x)
{
"success": false,
"message": "자료가 존재하지 않습니다."
}
5.3 2xx : Success, 4xx: Client errors, 5xx: Server errors
성공에 대한 상태 코드를 200으로 통일해도 크게 상관은 없다.
하지만 상태 코드만으로도 요청이 어떻게 처리됐는지 알 수 있도록 적절한 상태 코드를 보내는 것이 좋다.
- 2xx: 서버가 클라이언트의 요청을 성공적으로 처리했다.
- 4xx: 클라이언트의 요청이 유효하지 않아 서버가 해당 요청을 수행하지 않았다.
- 5xx: 서버 오류로 인해 요청을 수행할 수 없다.
5.4 2xx: Success. 성공
서버가 클라이언트의 요청을 성공적으로 처리했다는 의미다.
- 200: OK. 클라이언트의 요청을 서버가 정상적으로 처리했다.
- 201: Created. 클라이언트의 요청을 서버가 정상적으로 처리했고 새로운 리소스가 생겼다. 새로운 자원이 추가되었거나, 수정 요청으로 자원의 내용이 변경되었을때 사용한다.
- 202: Accepted. 클라이언트의 요청은 정상적이나, 서버가 아직 요청을 완료하지 못했다. 비동기로 처리 할때 발생하는 상태 코드이다. 클라이언트가 요청의 완료 여부를 확인할 수 있는 방법을 제공해야 한다.(작업의 상태를 확인할 수 있는 URI)
- 204: Not Content. 클라이언트의 요청은 정상적이다. 하지만 컨텐츠를 제공하지 않는다. 204 상태 코드는 자원의 삭제 요청, 자료 수정 요청의 결과가 변경된 내용이 없을때 같은 상황에서 사용한다. 클라이언트는 자원 삭제를 요청했고 이 요청이 유효하니 서버는 해당 자원을 삭제했다. 더 이상 응답할 컨텐츠가 없기 때문에 204로 응답한다. 200으로 응답하고 body에 null 등으로 응답하는 것과 다르다. 204는 body가 아예 존재하지 않는 경우다.
5.5 4xx: Client errors.
클라이언트의 요청이 유효하지 않아 서버가 해당 요청을 수행하지 않았다는 의미다.
라이언트에서 에러 발생 원인을 정확하게 알 수 있도록 파라미터의 위치, 사용자의 입력 값, 에러 이유를 명시하는 것이 좋다.
- 400: Bad Request. 클라이언트의 요청이 유효하지 않아 더 이상 작업을 진행하지 않은 경우 요청에 대한 유효성 검증 과정에서 에러가 발생할 경우 400 상태 코드를 응답한다.
- 401: Unauthorized(승인되지 않음). 클라이언트가 인증되지 않았기 때문에 작업을 진행할 수 없는 경우 403 상태코드와 헷갈릴 수 있지만, 401은 인증, 402은 권한에 대한 내용이다. 인증: 로그인 시 사용자가 주장하는 사용자인지 인증되지 않은 경우 권한: 특정 글을 조회할 권한이 없음.
- 403: Forbidden(금지된). 클라이언트가 권한이 없기 때문에 작업을 진행할 수 없는 경우 인증된 클라이언트가 권한이 없는 자원에 접근할 때 응답하는 상태코드다.
- 404: Not Found. 클라이언트가 요청한 자원이 존재하지 않는 경우 인터넷에서 가장 흔하게 볼 수 있는 에러다. 존재하지 않은 경로를 요청하거나 존재하는 경로에 자원이 존재하지 않은 경우 404 상태 코드로 응답한다.
- 405: Method Not Allowed. 클라이언트의 요청이 허용되지 않는 HTTP 메소드(GET, POST, PUT, DELETE)인 경우 URI는 존재하지만 해당 자원이 지원하지 않는 메소드드인 경우 405 상태 코드를 응답한다. 허용되는 메소드에 자원이 존재하지 않는다면 404 상태 코드를 사용하고, 허용되지 않는 메소드를 요청한다면 405 상태 코드를 사용한다.
- 409: Conflict. 클라이언트의 요청이 서버의 상태와 충돌할 경우 충돌이라는 것은 추상적이기 때문에 정의하기 나름이다. 다른 상태코드들처럼 명확하지 않기때문에 개발자간 규칙을 협의한 후 사용해야 한다. 주로 다른 상태 코드에 속하기 애매한 상황에 409 상태 코드를 사용한다. 예를 들어 비즈니스 로직에 의해 요청이 받아들여지지 않은 경우, 다른 4xx 상태 코드에 속하기 애매하기 때문에 409 상태 코드를 사용한다.
- 429: Too Many Request. 클라이언트가 일정 시간동안 너무 많은 요청을 보낸 경우 비정상적인 방법으로 자원을 요청하는 경우 429 상태 코드를 사용한다. 서버가 감당하기 힘든 요청이 지속적으로 들어오면 다른 작업을 처리하지 못할 수 있다. 429 상태 코드는 이런 경우 일정 시간 뒤 요청할 것을 나타내는 것이다.(HTTP hearder Retry-After를 이용한다)
5.6 5xx: Server erros.
서버 오류로 인해 요청을 수행할 수 없다는 의미다.
API 서버의 응답에서 5xx 오류가 발생해서는 안된다. API에서는 완벽한 예외처리를 통해 오류 코드를 방지해야 한다.
500 오류는 개발자의 실수로 발생할 여지가 크다.
- 필수값, 유효성 확인 없이 비즈니스 로직을 진행하는 경우
- 외부 API에서 받은 객체를 확인하지 않은 경우
'기타' 카테고리의 다른 글
[Docker] Docker 호스트에 원격으로 배포하기(docker compose 이용) (1) | 2021.12.18 |
---|---|
[MacBook]맥북에게 5000번 포트를 빼앗겼을때 - error: bind EADDRINUSE null:5000 에러 해결 (8) | 2021.12.18 |
SVN checkout시 SSL 에러 해결방법(CentOS) (0) | 2021.11.05 |
[JWT] 서버 인증 이해하기 - JWT란, 서버 인증 / 토큰 인증 (1) | 2020.10.07 |
[Git] 깃허브란? Github 시작하기 - 1 (0) | 2020.06.18 |