[포스코x코딩온] KDT-Web-8 8주차 회고2 Restful API Naming Convention

Yunes·2023년 8월 24일
1

[포스코x코딩온]

목록 보기
23/47
post-thumbnail

REST 란 무엇인가

Rest는 REpresentational State Transfer 의 약자로 클라이언트와 서버가 데이터를 주고받는 방식에 관한 아키텍처 스타일이다.

REST 는 가상머신간의 호출에 있어서 Remote Procedure Call (RPC), Common Object Request Broker Architecture (CORBA), Simple Object Access Protocol (SOAP) 같은 복잡한 기술대신 간단한 HTTP 를 사용하고자 하는 아이디어에서 만들어졌다.

REST 는 자신만의 원칙과 제약조건들이 있는데 특정 서비스 인터페이스가 RESTful 하다고 말하기 위해선 이 원칙들이 지켜져야 한다.

REST 아키텍처 스타일을 따르는 Web API 를 REST API 라고 부른다.

RPC : 프로그램이 원격 서버의 기능이나 프로시저를 마치 로컬인 것처럼 실행하여 분산 컴퓨팅을 용이하게 하는 통신 프로토콜
CORBA : 다양한 프로그래밍 언어와 플랫폼에 걸쳐 분산된 개체 간의 상호 운용성을 가능하게 하는 미들웨어 기술
SOAP : 웹 서비스 구현 시 구조화된 정보를 교환하기 위한 프로토콜로 메시지 형식으로 XML 을 활용하고 서로 다른 시스템 간의 통신을 허용한다.

REST 는 반드시 지켜야 하는게 아니다! 그보단 인터넷 기반 컴퓨터 시스템간의 상호운용성을 보장하기 위한 아키텍처 스타일이다.

6가지 REST 원칙

1. Uniform Interface 인터페이스 일관성 ⭐️

일관된 규칙을 인터페이스에 적용하여 시스템 아키텍쳐 전반을 단순화하고 상호작용의 가시성을 향상시킬 수 있다.

제약조건

  • Identification of resources
    : 각 리소스는 유일하게 식별 가능해야 한다.
    => 리소스가 URL 로 식별되어야 한다.

  • Manipulation of resources through representations
    : 리소스는 서버 응답에서 균일하게 표현되어야 한다. API 소비자는 이 표현들을 사용해서 서버의 리소스 상태를 수정한다.
    => 리소스를 삭제, 수정, 입력시 HTTP 메시지에 표현을 담아 전송한다.

  • Self-descriptive messages
    : 각 리소스 표현은 메시지 전달에 대한 충분한 정보와 이 리소스에 대해 할 수 있는 추가적인 작업에 대한 정보를 제공해야 한다.
    => 메시지만 봐도 무슨 리소스인지 해석할 수 있어야 한다.

  • Hypermedia as the engine of application state(HATEOAS)
    : 하이퍼미디어를 애플리케이션의 상태를 관리하기 위한 메커니즘으로 사용한다. REST Api 를 사용하는 클라이언트가 전적으로 서버와 동적인 상호작용이 가능하도록 해야 한다.
    => 링크를 써서 페이지를 이동

Uniform Interface 는 중요하니 조금 더 자세히 알아봤다.

먼저 시중 사이트중에 http 를 아직도 사용중인 사이트를 찾아봤다.

gmarket mobile

요즘은 보안문제로 인해 대부분 https 를 사용하는 것 같은데 다행히 금방 찾을 수 있었다.

저 사이트에 들어가보고 개발자모드를 켜서 네트워크 - 헤더 - 요청헤더를 자세히 살펴볼 수 있다.

HTTP 헤더 : 클라이언트와 서버가 요청 / 응답으로 부가적인 정보를 전송하는 HTTP 메시지를 말하며 대소문자를 구분하지 않는 이름과 콜론, 값으로 구성된다. 쿠키, 세션방식의 인증을 사용시 토큰을 헤더에 담아 전달한다.

먼저 다음과 같은 메시지가 있을때 메시지만 보고 어떤 리소스를 전달하는지 해석할 수 있을까?

GET /yes24 HTTP/1.1

위와 같은 메시지만 있다면 무엇에 관한 것인지 알기 어렵다.

그래서 Host 를 추가해서 메시지가 gmarket 을 향한 것임을 알려준다.

GET /yes24 HTTP/1.1
Host: minishop.gmarket.co.kr

이런 식으로 HTTP 메시지만 봐도 어떤 내용인지, 어떤 리소스인지, 무엇을 담고 있는지 등에 대해 알 수 있어야 한다. 이러한 REST 제약 조건을 지킨 아키텍처 스타일을 REST 라고 하며 이러한 API 를 RESTful API 라고 한다.

2. Client-Server 클라이언트 - 서버 구조

클라이언트 서버 디자인 패턴은 사용자 인증, context (세션, 로그인 정보) 등을 관리하는 유저 인터페이스 client 와 데이터 저장소와 관련되어 있고 API 제공, 비즈니스 로직 처리 및 저장을 책임지는 server 를 분리시켜 서로간 의존성을 줄이고 독립적으로 발전하도록 한다.

3. Stateless 무상태

HTTP 프로토콜은 stateless protocol 이라 REST 도 무상태성을 갖는다.

클라이언트에서 서버로의 각 요청은 반드시 요청을 완전히 완료하고 이해하기 위해 필요한 모든 정보를 포함해야 한다.

서버는 이전에 저장된 컨텍스트 정보의 이점을 취할 수 없다. 이런 이유로 클라이언트 앱은 반드시 세션 상태를 전적으로 유지해야 한다.

서버는 각각의 요청을 별개의 것으로 인식하고 처리한다.

4. Cacheable 캐시 처리 기능

응답은 반드시 암묵적이거나 명시적으로 캐시 처리 가능여부를 나타내야 한다. 캐시처리가 가능할 경우 클라이언트 앱은 응답 데이터를 이후 동일한 요청과 특정 기간동안 재사용할 권리를 갖게 된다.

5. Layered System 계층화

구성 요소 동작을 제한하여 아키텍처가 계층적 구조로 구성되도록 한다.

6. Code on Demand (optional)

REST 는 applet 이나 script 형태의 코드를 받아서 클라이언트에서 실행할 수 있다.

Resource, 자원이란?

이름이 지정될 수 있는 모든 정보를 리소스라고 할 수 있다. 예를 들어 문서, 이미지, 일싲거 서비스 등이 될 수 있다.

자원은 데이터, 데이터를 설명하는 metadata, 클라이언트가 다음 상태로 전환되는데 도움이 될 hypermedia link 등을 포함한다.

RESTful 네이밍 컨벤션

Singleton and Collection Resources - 단수형, 복수형 리소스

예를 들어 users 는 복수형 리소스이고 user 는 단수형 리소스다.

만약 유저를 생성하거나 특정 유저를 조회하는 API 를 어떻게 구성해야 할까?

일반적으로 사용자는 다른 대상, 이 예시에선 다른 포스트가 존재하는지 여부를 알 수 없기에 https://mysite.com/post/1 보다는 https://mysite.com/posts/1 와 같이 복수 명사를 사용하는 것이 권장된다.

stackoverflow 에서도 코드에 대응하는 방식을 생각해 보라는 글이 있었다.

유저를 생성하는 것은 유저 배열에 하나의 유저를 추가하는 것이니 POST /users 가 적절해 보인다.

유저를 조회하는 것도 유저 배열중 하나의 유저를 조회하는 것이니 GET /users/:id 가 자연스럽다.

필수적으로 지켜야하는 것은 아니나 단수와 복수를 혼합해서 사용시 기준이 없어지거나 헷갈릴 수 있으니 한가지 방식을 사용하는게 더 적절하며 그렇다면 그중에서도 복수형 리소스를 사용하는 것이 더 바람직해 보인다.

복수 명사를 사용하자.

엔드포인트에서 동사 대신 명사를 사용하자

REST API 네이밍시 동사보다 명사를 사용하는 것이 권장된다. HTTP 에선 HTTP 메소드가 이미 GET, PUT, PATCH, DELETE 라는 동작을 CRUD (Create, Read, Update, Delete) 동사의 형태로 나타낸다.

따라서 다음과 같은 형태로 사용하는 것이 적절해 보인다.

GET  /getPosts         -->  GET  /posts
POST /createPost       -->  POST /posts
GET  /getPostById/1    -->  GET  /posts/1
/device-management/managed-devices 

/device-management/managed-devices/{device-id} 

/user-management/users

/user-management/users/{id}

HTTP 메소드로 엔드포인트가 무슨 일을 할지 나타내기에 동사 대신 명사를 사용하자

에러 핸들링을 위해 상태 코드를 사용하자

API 요청에 응답시 항상 상태 코드를 포함해야 사용자가 요청이 성공했는지, 실패했는지 알 수 있다.

  • 100 ~ 199 : 정보 응답 ex) 102 는 리소스가 진행중임을 나타낸다.
  • 300 ~ 399 : Redirect ex) 301 은 리소스가 영구적으로 이동 페이지로 이동되었음을 의미한다.
  • 400 ~ 499 : 클라이언트 측 에러 ex) 400 은 요청이 잘못되었다는 것을 말하고 404 는 리소스를 찾을 수 없음을 나타낸다.
  • 500 ~ 599 : 서버 측 에러 ex) 500 은 내부 서버 에러를 말한다.

관계를 나타내기 위해 계층 구조의 엔드포인트를 사용하자

예를 들어 다수의 사용자가 사용하는 블로그 플랫폼에서 여러 게시물은 각각 다른 사용자들에 의해 작성된다.
/posts/author

이와 같이 게시물들은 각각의 댓글들을 갖고 있다.
/posts/postId/comments

그러나 3단계 이상 중첩시 가독성이 떨어지므로 너무 많이 중첩하지 않는 것을 권장한다.

URL vs URI
URI, Uniform Resource Identifier
: 식별자, 자원 자체를 식별한다. 지도, naver.com
URL, Uniform Resource Locator
: 식별자 + 위치, 웹 사이트 주소뿐 아니라 위치를 동시에 보여준다. 지도, 좌표 https://naver.com

데이터를 받을 때 필터링, 분류, 페이지네이션을 사용하자

막대한 양의 데이터를 가져오는 경우 느려질 수 있다. 그러니 REST API 는 미리 분류하여 일부 데이터만 가져오도록 할 수 있다.

/posts?tags=javascript

버전을 명시하자

REST API 는 여러 버전을 지원하여 사용자들이 최신 버전이 아니더라도 사용할 수 있게 해야 한다. 가장 흔히 버전을 관리하는 방법은 Semantic Versioning 이다.

2.1.2

첫 번째 숫자 : 주 버전
두 번째 숫자 : 부 버전
세 번째 숫자 : 패치 버전

mysite.com/v1

계층 구조를 나타내기 위해 / 슬래시 구분자를 사용하자

/device-management
/device-management/managed-devices
/device-management/managed-devices/{id}
/device-management/managed-devices/{id}/scripts
/device-management/managed-devices/{id}/scripts/{id}

URI 의 가독성을 높이기 위해 - 하이픈을 사용하자

http://api.example.com/devicemanagement/manageddevices/
http://api.example.com/device-management/managed-devices 	/*This is much better version*/

밑줄을 사용하지 말자

폰트에 따라 밑줄은 보기 어려울 수 있다. 가독성을 위해 밑줄을 사용하지 말자

http://api.example.com/inventory-management/managed-entities/{id}/install-script-location  //More readable

http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation  //Less readable

소문자를 사용하자

편의를 위해 URI 경로에 소문자를 사용하자

http://api.example.org/my-folder/my-doc       //1
HTTP://API.EXAMPLE.ORG/my-folder/my-doc     //2
http://api.example.org/My-Folder/my-doc       //3

파일 확장자를 포함하지 말자

/device-management/managed-devices.xml  /*Do not use it*/

/device-management/managed-devices 	/*This is correct URI*/

절대! CRUD 함수명을 URI 에 사용하지 말자

URI 는 오직 유일하게 리소스를 식별하기 위해 사용하지 동작을 식별하기 위해 사용하는 것이 아니다.

HTTP GET /device-management/managed-devices  			//Get all devices
HTTP POST /device-management/managed-devices  			//Create new Device

HTTP GET /device-management/managed-devices/{id}  		//Get device for given Id
HTTP PUT /device-management/managed-devices/{id}  		//Update device for given Id
HTTP DELETE /device-management/managed-devices/{id}  	//Delete device for given Id

쿼리 컴포넌트를 사용해 URI 복수형을 필터링하자.

/device-management/managed-devices
/device-management/managed-devices?region=USA
/device-management/managed-devices?region=USA&brand=XYZ
/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

리소스를 나타내기 위해 명사를 사용하자

  • document 이름으로 단수 명사를 사용한다.
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin
  • collection 이름으로 복수 명사를 사용한다.
/device-management/managed-devices
/user-management/users
/user-management/users/{id}/accounts
  • store 이름으로 복수 명사를 사용한다.
/song-management/users/{id}/playlists

RESTful 은 이해하기 쉽고 사용하기 쉬운 REST API 를 만드는 것이 목적이다. 성능 향상보다는 일관적인 컨벤션으로 API 의 이해도, 호환성을 높이는 것을 목표로 한다.

레퍼런스

blog
joomn11 - REST Api (Hateoas)
팀드모네 IT Blog - REST 제약조건
하나몬 - REST API란?
호박너구리 블로그 - REST API 컨벤션
docs
restfulapi.net - REST
restfulapi.net - resource naming
meta for developers - Graph API Reference
google cloud - 이름 지정 규칙
reference
gearheart - REST API
freecodecamp - REST Endpoint Design Examples

profile
미래의 나를 만들어나가는 한 개발자의 블로그입니다.

2개의 댓글

comment-user-thumbnail
2023년 8월 26일

잘 참고하겠습니다 좋은 내용 감사합니다 😁

1개의 답글