REST API 제대로 이해하기

hahaha·2021년 12월 20일
0

REST API를 어렴풋이 이해했다고 생각했는데,
PUT 방식에서 Query Parameter를 보내는 것에 이상함을 못느끼면서... 제대로 다시 알아보고자 한다.
그렇게 API를 만들면서 제대로 알지 못했던 것이다... 😂

REST API(RESTful API)

  • REST 아키텍처의 제약 조건(디자인 원칙)을 준수하는 API
    - API(Application Programming Interface)는?
    • 애플리케이션 소프트웨어를 구축하고 통합하는 정의 및 프로토콜 세트
    • 애플리케이션이나 디바이스가 서로 간에 연결하여 통신할 수 있는 방법을 정의하는 규칙 세트

REST(Representational State Transfer)

  • 프로토콜이나 표준이 아닌 아키텍처 원칙 세트
  • 클라이언트
    - 액세스를 수행하는 애플리케이션이나 서비스
  • 서버
    - 리소스가 포함된 애플리케이션이나 서비스

REST의 탄생

  • 2000년도에 Roy Fielding의 박사학위 논문에서 최초로 소개되었다.
  • Roy Fielding은 HTTP의 주요 저자 중 한 사람으로, 그 당시 웹(HTTP) 설계의 우수성에 비해 제대로 사용되지 못하는 모습에 안타까워하며 웹의 장점을 최대한 활용할 수 있는 아키텍처로써 REST를 발표했다.

REST 구성

1. 자원(Resource)

  • URI

2. 행위(Verb)

  • HTTP Method

3. 표현(Representations)

REST 디자인 원칙

1. Uniform Interface

  • 요청 출처에 무관하게, 동일한 리소스에 대한 모든 API 요청은 동일하게 보여야 한다.
  • 특정 언어나 플랫폼에 종속되지 않고 사용 가능해야 한다.

2. Client - Server

  • 클라이언트와 서버는 서로 간에 완전히 독립적이어야한다.
  • 클라이언트가 알아야 하는 유일한 정보는 요청된 리소스의 URI
  • 서버는 HTTP를 통해 요청된 데이터에 전달하는 것 외에 클라이언트 수정을 하지 않아야 한다.

3. Stateless

  • 모든 요청은 그 요청을 처리하기 위해 필요한 모든 정보를 포함해야 한다.
  • 서버는 클라이언트 요청과 관련된 데이터를 저장할 수 없다.
    - 세션, 쿠키와 같은 컨텍스트 정보를 따로 저장하여 관리하지 않는다.
    - 서버는 들어오는 요청만을 단순히 처리하면 된다.

    💡 HTTP 프로토콜이 Stateless Protocol 이기 때문이다.

4. Cacheable

  • 리소스를 클라이언트 또는 서버측에서 캐싱할 수 있어야 한다.
  • HTTP 표준에서 사용하는 Last-Modified, E-Tag 등을 이용하여 캐싱 구현이 가능하다.

    💡 HTTP 웹 표준을 그대로 사용하기에, 웹에서 사용하는 기존 인프라 활용이 가능하다.

5. 계층 구조 아키텍처

  • 클라이언트와 서버 애플리케이션이 서로 간에 직접 연결되어 있다고 가정하지 않는다.
  • 서버는 다중 계층으로 구성되어 통신 루프에 다수의 서로 다른 중개자가 존재할 수 있다.
    - LB, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있다.
    - PROXY, GateWay와 같은 네트워크 기반의 중간매체를 사용할 수 있다.

6. Self-descriptiveness

  • REST API 메세지만 보고도 이를 쉽게 이해할 수 있는 자체 표현 구조로 이루어져 있다.

7. Code-On-Demand(optional)

  • 일반적으로 정적 리소스를 전송하지만, 특정 경우에 실행 코드(script)를 응답으로 포함할 수 있다.

REST API 디자인 가이드

중심 규칙

  1. URI는 정보의 자원을 표현해야 한다.
    (리소스명은 주로 명사로 나타낸다.)
    GET /members/delete/1
    -> URI에 자원이 아닌 행위에 대한 표현(delete)이 들어가면 안된다.
  2. 자원에 대한 행위는 HTTP Method로 표현한다.
    DELETE /members/1

URI 설계 시 주의할 점

  1. 슬래시 구분자(/)는 계층 관계를 나타내는 데 사용
  2. 마지막 문자로 슬래시(/)를 포함하지 않는다.
  3. 하이픈(-)은 불가피하게 긴 경로의 가독성을 높이는 데 사용된다.
  4. 언더바(_)는 사용하지 않는다.
  5. 주로 소문자를 사용한다.
  6. 파일 확장자는 포함시키지 않는다.
    (Accept header를 통해 나타낸다.)

자원을 표현하는 Collection과 Document

  • 리소스를 의미하며 URI에 표현된다.
  • collection: document의 집합 (주로 복수로 사용)
  • document: 문서, 한 객체
    http://restapi.example.com/sports/soccer/players/13
    -> collection: sports, players
    -> document: soccer, 13

HTTP Method

종류

GET

  • 특정 리소스를 가져올 때
  • 대부분 body나 payload를 담지 않는다.

POST

  • 새로운 리소스를 생성하거나 독립적인 명령을 실행할 때
  • 요청 본문의 유형은 Content-Type 헤더로 나타낸다.

PUT

  • 현존하는 리소스의 전체적인 업데이트를 할 때
  • 리소스가 있으면 업데이트하고, 없는 경우 생성한다. -> 덮어쓰기 개념
  • POST는 Collection에서 사용되고, PUT은 Document에서 수행된다.

PATCH

  • 현존하는 리소스의 부분 업데이트를 할 때
  • 지원하는 브라우저가 현저히 적다.

DELETE

  • 리소스를 삭제할 때

기타 메소드

OPTIONS
CONNECT
TRACE

속성

1. Safe

  • 메소드를 계속 호출해도 리소스를 변경하지 않는다.
  • 대표적으로 GET 이 포함된다.

2. Idempotent(멱등성)

  • 메소드를 계속 호출해도 결과가 동일하다.
  • 동일한 요청을 한 번 보내는 것과 여러번 연속으로 보내는 것이 같은 효과를 지닌다.
  • POST, PATCH 는 멱등하다고 할 수 없다.

3. Cacheable

  • 캐싱이 가능해 데이터를 효율적으로 가져올 수 있다.
  • 주로 GET, HEAD 에 사용된다.

요약표

HTTP Status Code

상태코드설명
1XX (조건부 응답)요청을 받았으며 작업을 계속 진행한다.
2XX (성공)요청을 성공적으로 처리했다.
3XX (리다이렉션)요청 완료를 위해 추가 작업 조치가 필요하다.
4XX (클라이언트 오류)요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
5XX (서버 오류)서버기 명백히 유효한 요청에 대해 충족을 실패했다.

자주 사용되는 코드

  • 200 (OK): 서버가 요청을 성공적으로 처리
  • 201 (Created): 성공적으로 요청되었으며, 새 리소스를 작성했다.
  • 400 (BadRequest): 서버가 요청 구문을 인식하지 못했다.
  • 401 (Unauthorized): 필요한 인증에 실패했다.
  • 403 (Forbidden): 서버가 요청을 거부하고 있다.
    - 권한이 없는 경우
  • 404 (Not Found): 서버가 요청한 페이지를 찾을 수 없다.
  • 500 (Internal Server Error): 서버에 오류가 발생하여 요청을 수행할 수 없다.
  • 502 (Bad Gateway): 서버가 게이트웨이나 프록시 역할을 하는 곳에서 잘못된 응답을 받았다.
  • 504 (Gateway Timeout): 서버가 게이트웨이나 프록시 역할을 하는 곳에서 제때 요청을 받지 못했다.

참고 문서

Request 객체

  1. req.params
  • URI에 포함된 변수
/user/:name URI에서,
https://user/1234
-> req.params.name = 1234
  1. req.query
  • URL의 ? 이후의 변수
https://query/search?searchWord=abcd
  1. req.body
  • URI에서 확인할 수 없다.
  • JSON, XML, Multi Form 등의 데이터를 담을 때 사용
profile
junior backend-developer 👶💻

0개의 댓글