본문 바로가기

Hub Web/Web

[Web] REST API와 URI 설계

728x90

📜 REST API란?


🔹 기존의 웹 서비스에서는 URI에 동사를 사용하여 어떤 작업을 수행하는지를 명시했다. 예를 들면, 다음과 같은 URI 구조이다.

GET / getUsers
POST / createUser
PUT / updateUser
DELETE / deleteUser

 

이러한 방식은 API의 설계를 명확하게 하기 위해 도움이 되었지만, REST API의 경우는 명사 중심의 자원을 표현하고 HTTP 메서드를 통해 어떤 작업을 수행하는지를 명시한다. 즉, URI에는 자원을 식별하는 명사를 사용하고, 해당 자원에 대한 행동은 HTTP 메서드로 나타낸다. 예를 들어, REST API에서는 다음과 같은 구조를 사용한다.

GET / users - 모든 사용자를 가져오는 자원
POST / users - 새로운 사용자를 생성하는 자원
PUT / users/{id} - 특정 ID의 사용자 정보를 업데이트하는 자원
DELETE / users/{id} - 특정 ID의 사용자를 삭제하는 자원

이런 식으로 URI는 자원을 명시하고, HTTP 메서드는 해당 자원에 대한 특정 동작을 정의한다. 

 

👻 REST API를 사용하는 이유


🔹 위의 내용만 봤을 때는 REST API를 왜 사용해야 하는 건지 와닿지가 않는다. REST API를 사용해야 하는 이유를 특징과 함께 설명한다.

 

[ REST API 의 특징 ]

 

1) 유연성과 확장성
    ◈ REST API는 자원을 중심으로 설계되므로, 새로운 자원을 추가하거나 기존 자원을 수정할 때 API의 구조를 크게 변경할 필요가 없다. 이는 유연성과 확장성을 높여준다.

 

2) Stateless (무상태성)
    ◈ 서버가 클라이언트의 상태를 기억하지 않는다. 즉, 각각의 요청은 서버에 저장되는 세션 정보나 상태 정보를 포함하지 않는다. 각 요청은 서버에 의해 독립적으로 처리되며, 이전 요청과 관련된 정보를 서버가 기억하지 않는다.
    ◈ 이러한 특성은 HTTP 프로토콜의 영향을 받기도 했으며 상태를 유지할 필요가 없으므로 서버 및 클라이언트의 구현이 간단해진다. 상태 관리를 위한 복잡한 로직이나 데이터베이스의 사용이 줄어든다.
    ◈ 서버가 클라이언트의 상태를 유지하지 않기 때문에 새로운 요청이 들어올 때마다 새로운 상태를 생성할 필요가 없다. 따라서, 서버는 더 많은 요청을 동시에 처리할 수 있다.

 

3) Cacheable
    ◈ HTTP의 가장 강력한 기능 중 하나인 캐싱을 사용하여 대량의 요청을 효율적으로 처리할 수 있고 응답시간이 빨라진다. 

    ◈ REST Server Transaction이 발생하지 않기에 전체 응답시간, 성능, 서버의 자원 이용률을 향상시킬 수 있다. (Last-Modified, E-Tag)

 

4) Self-descriptiveness (자체 표현 구조)
    ◈ REST API의 메시지만 보고도 이를 쉽게 이해할 수 있다.

 

즉, REST 기반으로 시스템을 분산하기에 확장성과 재사용성을 높일 수 있고 유지보수 및 운용을 편리하게 할 수 있다. 더해서 REST는 HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있고 또한, Stateless 특성으로 인해 로직이 간단해지고 더 많은 요청을 동시에 처리할 수 있다. (RESTful은 일반적으로 REST 아키텍처를 구현하는 웹서비스를 나타내는 용어이다. )

 

🚧 REST API 장단점


[ REST API 의 장점 ]

  • HTTP 프로토콜 인프라를 그대로 사용하기에 REST API를 위한 별도의 인프라를 구축할 필요가 없다.
  • HTTP 프로토콜의 표준을 최대한 활용하여 추가적인 장점을 가져가고 프로토콜을 따르는 모든 플랫폼에서 사용이 가능하다.
  • REST API 메시지가 의도하는 바를 명확히 나타낸다.
  • 서버와 클라이언트의 역할을 명확히 분리한다.

REST API 의 단점 ]

  • REST API의 설계 원칙이 있긴 하지만 표준이 명확하게 정의되어 있지 않다.
  • 사용할 수 있는 메소드가 제한적이다. -> HTTP Method 형태가 제한적이다.
  • REST API는 HTTP를 기반으로 하기 때문에 기본적으로는 보안에 취약할 수 있다. 따라서 인증 및 권한 부여, 데이터 암호화 등의 보안 기능을 추가해야 한다.
  • 구형 브라우저가 아직 제대로 지원해주지 못하는 부분이 존재한다 (PUT, DELETE).

⚙️ REST API 컨벤션


[ 컬렉션 단수 vs 복수 ]

 

🔹 DB의 유저 Table/Collection을 생각해 보면 우선, 유저 array를 받아오는 요청은 여러 유저 정보를 받아오는 것이니 users가 자연스럽다. (GET /users) 그리고 유저를 생성하는 것도 유저 array에 하나의 유저를 추가하는 것이니 /users 에 요청을 날린다. 특정 id의 유저를 받아오는 api도 유저 array 중에서 고르는 것이기에 /users/:id 가 자연스럽다.

 

몇몇 글을 살펴보면 복수를 선호하지만 단수를 쓰는 것도 큰 상관은 없다는 의견도 많다. 하지만, 모두 공통적으로 단수와 복수를 혼합해서 사용하는 것은 지양해야 한다고 말한다.

(혼용해서 사용하게 된다면, 기준이 없어지고 새로 api를 만들거나 api를 가져다 쓸 때 쉽게 헷갈리거나 실수하게 되기 때문이다.)

 

[ URI 명사 사용 ]

 

🔹 처음 시작했던 서론에서 볼 수 있듯이, 컬렉션에 동사를 사용하는 방식은 각각의 작업을 URI에 동사로 표현한다. 반면에 명사를 사용하는 방식은 각각의 작업을 URI에 자원을 나타내는 명사로 표현하고, HTTP 메서드를 사용하여 작업을 수행한다.

 

[ URI 밑줄(_) 대신 하이픈(-) ]

 

🔹 주소를 표현하는 URI가 길어지는 경우 밑줄 보다는 하이픈을 사용하는 것이 좋다.

GET /user_profiles -> GET /user-profiles
POST /user_profiles -> POST /user-profiles

 

[ URI 소문자 사용 ]

 

🔹 윈도우 운영체제라면 디렉터리나 파일이름에서 대소문자를 구분하지 않으나, 리눅스 혹은 유닉스 계열의 서버라면 대소문자를 구분해야 하기 때문에 소문자로 통일하는 것이 선호된다.

 

[ 컬렉션 필터링 ]

 

🔹 REST API에서는 컬렉션을 단일 URI로 표시한다. 이 경우 컬렉션의 일부만 필요할 때에도 컬렉션 전체를 가져오는 문제가 발생할 수 있다. 예를 들어 GET /users 는 모든 사용자를 조회할 것이다. 이럴 때 쿼리 스트링을 사용해서 필터링을 수행할 수 있다. 만약 역할 id가 1인 사용자만 조회하고 싶으면 GET /users?role=1로 필터링을 수행할 수 있다.

 

[ HTTP 상태코드 ]

 

📸 참조


https://restfulapi.net/resource-naming/

https://velog.io/@rlcjf0014/Back-end-Restful-API