WIL | RESTful API, package.json

isthis·2021년 11월 21일
0
post-thumbnail

RESTful API

RESTful API란?

우선, RESTful이라는 용어는 REST 아키텍쳐 스타일을 따르면서 구현된 시스템을 지칭할 때 종종 사용된다.

아키텍쳐 스타일 : 그 스타일을 따르는 아키텍처가 지켜야 하는 **제약조건들의 집합**

따라서 RESTful API란 REST라는 아키텍쳐 스타일을 따르면서 구현된 API라고 할 수 있다. (그냥 REST API라고도 부른다.)

REST API에 대한 간단한 설명

원래 있던 방법보다 더 쉽고 사람이 읽기 편한 방식으로 원칙을 세워놨고, 개발자들의 생산성과 상호작용을 증진시키는것에 목적이 있다. (다른 방식에 비해 조금 더 아름답다고 이해해도 된다.)
즉, http 메소드와 uri를 의미를 두고 사용하여 이런 것들만 보고도 어떤 기능을 하는 API구나 하고 알 수 있게 만든 것이다.

REST란?

REST를 기반으로 설계된 것을 RESTful이라 하는 것은 이제 알았다. 그렇다면 REST라는 아키텍쳐가 구체적으로 무엇일까.

REST 아키텍쳐의 정의

REST는 웹과 같은 분산 하이퍼 미디어 시스템에서 사용하는 통신 네트워크 아키텍쳐로, 네트워크 아키텍쳐의 원리 모음을 의미한다.

조금 더 자세히 해석해보자.
웹은 전송 방식으로 HTTP(프로토콜)를, 식별 방법(식별자)으로 URI를 사용하는데 HTTP와 URI의 단순하고 간결한 장점을 계승하여 웹의 장점을 최대한 활용하는 아키텍쳐 스타일이 REST이다.
따라서 REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 이라고 볼 수 있으며, 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는다.

HTTP?
웹에서 GET, POST 등의 메서드를 사용하여 정보를 주고받는 프로토콜

REST의 구체적인 개념

REST를 조금 더 구체적으로 알아보자.

  • HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE, PATCH)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.
    즉, REST는 자원 기반의 구조(ROA, Resource Oriented Architecture) 설계의 중심에 Resource가 있고 HTTP Method를 통해 Resource를 처리하도록 설계된 아키텍쳐를 의미한다.
  • 따라서 웹 사이트의 이미지, 텍스트, DB 내용 등의 모든 자원에 고유한 ID인 HTTP URI를 부여한다.
  • CRUD Operation
    • Create : 생성(POST)
    • Read : 조회(GET)
    • Update : 수정(PUT, PATCH)
    • Delete : 삭제(DELETE)
    • HEAD: header 정보 조회(HEAD)

자원 기반 구조(ROA)

"Resource Oriented Architecture"
ROA란 웹의 모든 리소스를 URI로 표현하고 구조적이고 유기적으로 연결하여 비 상태 지향적인 방법으로 정해진 method만을 사용하여 리소스를 사용하는 아키텍쳐이다.
이는 4가지의 고유한 속성과 연관되어 진다. ( REST는 이 속성들을 지향한다 )

  • Addressablilty
  • Connectedness
  • Statelessness
  • Homogeneous Interface
Addressablilty (주소로 표현 가능함)
  • 제공하는 모든 정보를 URI로 표시할 수 있어야 한다.
  • 직접 URI로 접근할 수 없고 HyperLink를 따라서만 해당 리소스에 접근할 수 있다면 이는 RESTful하지 않은 웹서비스이다.
Connectedness (연결됨)
  • 일반 웹 페이지처럼 하나의 리소스들은 서로 주변의 연관 리소스들과 연결되어 표현(Presentation)되어야 한다.
  • 예를 들면,
<user>
  <name>HJ</name>
</user> 

위 예시는 연결되지 않은 독립적인 리소스이다.

<user>
  <name>HJ</name>
  <address>HJ/seoul/</address>
  <phone>HJ/010</phone>
</user>

위 예시는 관련 리소스(address, phone)가 잘 연결된 리소스의 표현이다.

Statelessness (상태 없음)
  • 현재 클라이언트의 상태를 절대로 서버에서 관리하지 않아야 한다.
  • 모든 요청은 일회성의 성격을 가지며 이전의 요청에 영향을 받지 말아야 한다.
  • 다시 또 코리아닷컴의 예를 들면 메일을 확인하기 위해 꼭 '..코리아닷컴../mailView.crd'에 접근하여 해당 세션을 유지한 상태에서 메일 리소스에 접근해야 한다. 이것이 바로 Statelessness가 없는 예이다.
  • 세션을 유지 하지 않기 때문에 서버 로드 발란싱이 매우 유리하다.
  • URI에 현재 state를 표현할 수 있어야 한다. (권장사항)
Homogeneous Interface (동일한 인터페이스)
  • HTTP에서 제공하는 기본적인 4가지의 method와 추가적인 2가지의 method를 이용해서 리소스의 모든 동작을 정의한다.
  • 리소스 조회 : GET
  • 새로운 리소스 생성 : PUT, POST (새로운 리소스의 URI를 생성하는 주체가 서버이면 POST를 사용)
  • 존재하는 리소스 변경 : PUT, PATCH
  • 존재하는 리소스 삭제 : DELETE
  • 존재하는 리소스 메타데이터 보기 : HEAD
  • 존재하는 리소스의 지원 method 체크 : OPTION
  • 대부분의 리소스 조작은 위의 method를 이용하여 대부분 처리 가능하다. 만일 이것들로만 절대로 불가능한 액션이 필요할 경우에는 POST를 이용하여 추가 액션을 정의할 수 있다. (되도록 지양하자)

REST아키텍쳐를 구성하는 스타일

그렇다면 REST의 제약조건에는 어떠한 것들이 있을까.(이번에는 목록만 간단하게 알아보자)

  • client-server(클라이언트/서버 구조)
    • 일관적으로 독립되어야 한다.
  • stateless(무상태)
    • 각요청 간 클라이언트의 Context는 서버에 저장되어서는 안 된다.
  • cache(캐시 처리 가능)
    • WWW에서와 같이 클라이언트는 응답을 Caching 할 수 있어야 한다.
  • uniform interface(인터페이스 일관성)
    • 아키텍처를 단순화하고, 작은 단위로 분리하여, 클라이언트-서버 파트별로 독립적으로 개선 될 수 있도록 한다.
  • layered system(계층화)
    • 클라이언트는 보통 대상 서버에 직접 연결 또는 중간 서버를 통해 연결되는지 모른다.
  • code-on-demand(optional)
    • 자바 애플릿/자바스크립트의 제공으로 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여, 기능을 확장 할수 있다.

이러한 스타일들을 잘 지켜서 설계된 API를 진정한 RESTful API라고 부를 수 있다.
그러면 오늘날의 RESTful API들은 이 스타일을 잘 지키고 있을까?

"대체로 잘 지키고 있다."

그러나, uniform interface에 속해있는 제약조건인 self-descriptive messages와 HATEOAS(Hypermedia As The Engine Of Application State)가 대체적으로 지켜지지 않고 있다.
첫 번째의 내용은 API 메시지만 보고도 어떤 API인지를 이해 할수 있는 자체 표현 구조를 가진다는 것이고, 두 번째는 애플리케이션의 상태는 Hyperlink를 이용해 전이되어야 한다는 것이다. 이 두 가지를 지키기 위해서는 복잡한 과정이 필요하여 잘 지켜지지 않고 있다. 그러나, 오늘날의 사람들은 이러한 제약조건을 지키지 않아도 REST의 목적만 달성하면 RESTful API라 통용하고 있는 듯하다.(명확하게 어떤 것이 RESTful API라는 규약같은 것이 없다.)

REST API 구성 요소

그렇다면 실제로 REST API를 구성하기 위한 요소에는 무엇이 있는지 알아보자.

  1. 자원(Resource) - HTTP URI
    • 모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.
    • 자원을 구별하는 ID는 ‘/groups/:group_id’와 같은 HTTP URI 다.
    • Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.
  2. 행위(Verb) - HTTP method
    • 리소스에 대한 행위를 표현한다.
    • HTTP 프로토콜은 GET, POST, PUT, DELETE, PATCH와 같은 메서드를 제공한다.
리소스/메서드POSTGETPUTDELETE
/customers새 고객 만들기모든 고객 검색고객 대량 업데이트모든 고객 제거
/customers/1오류고객 1에 대한 세부 정보 검색고객 1이 있는 경우 고객 1의 세부 정보 업데이트고객 1 제거
/customers/1/orders고객 1에 대한 새 주문 만들기고객 1에 대한 모든 주문 검색고객 1의 주문 대량 업데이트고객 1의 모든 주문 제거
  1. 표현(Representations) - JSON, XML 등
    • 리소스에 대한 표현이다.
    • Client가 자원의 상태(정보)에 대한 조작을 요청하면 Server는 이에 다양한 (json, xml, text, rss 등) 표현으로 응답(Representation)을 보낸다.

REST API Design Guide

  1. REST API는 리소스를 중심으로 디자인되며, 클라이언트에서 액세스할 수 있는 모든 종류의 개체, 데이터 또는 서비스가 리소스에 포함된다.

  2. 리소스마다 해당 리소스를 고유하게 식별하는 URI인 식별자가 있다.

    https://works.com/orders/1
  3. 클라이언트가 리소스의 표현을 교환하여 서비스와 상호 작용한다.
    많은 Web API가 교환 형식으로 JSON을 사용한다.

  4. 가능하다면 리소스 URI는 동사(리소스에 대한 작업)가 아닌 명사(리소스)를 기반으로 해야 한다.(가능한 동사는 HTTP 메서드를 통해서 표현한다.) 또한, 리소스 URI를 컬렉션/항목/컬렉션 보다 더 복잡하게 요구하지 않는 것이 좋다. + 컬렉션을 적을 때는 복수형을 사용하는 것이 명확하다.

설계 방법에 대해 더 구체적으로 알아보자.

REST API 설계 기본 규칙

- 리소스 원형(참고)
  - 도큐먼트 : 객체 인스턴스나 데이터베이스 레코드와 유사한 개념
  - 컬렉션 : 서버에서 관리하는 디렉터리라는 리소스
  - 스토어 : 클라이언트에서 관리하는 리소스 저장소
  (컬렉션은 객체의 집합, 도큐먼트는 객체라고 생각하면 된다.)
  1. URI는 정보의 자원을 표현해야 한다.
    • resource는 동사보다는 명사를, 대문자보다는 소문자를 사용한다.
    • resource의 도큐먼트 이름으로는 단수 명사를 사용해야 한다.
    • resource의 컬렉션 이름으로는 복수 명사를 사용해야 한다.
    • resource의 스토어 이름으로는 복수 명사를 사용해야 한다.
      • Ex) GET /Member/1 -> GET /members/1
  2. 자원에 대한 행위는 HTTP Method(GET, PUT, POST, DELETE 등)로 표현한다.
    • URI에 HTTP Method가 들어가면 안된다.
      • Ex) GET /members/delete/1 -> DELETE /members/1
    • URI에 행위에 대한 동사 표현이 들어가면 안된다.(즉, CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.)
      • Ex) GET /members/show/1 -> GET /members/1
      • Ex) GET /members/insert/2 -> POST /members/2
    • 경로 부분 중 변하는 부분은 유일한 값으로 대체한다.(즉, :id는 하나의 특정 resource를 나타내는 고유값이다.)
      • Ex) student를 생성하는 route: POST /students
      • Ex) id=12인 student를 삭제하는 route: DELETE /students/12

REST API 설계 규칙

  1. 슬래시 구분자(/ )는 계층 관계를 나타내는데 사용한다.

    • Ex) http://restapi.example.com/houses/apartments
  2. URI 마지막 문자로 슬래시(/ )를 포함하지 않는다.

    • URI에 포함되는 모든 글자는 리소스의 유일한 식별자로 사용되어야 하며 URI가 다르다는 것은 리소스가 다르다는 것이고, 역으로 리소스가 다르면 URI도 달라져야 한다.
    • REST API는 분명한 URI를 만들어 통신을 해야 하기 때문에 혼동을 주지 않도록 URI 경로의 마지막에는 슬래시(/)를 사용하지 않는다.
    • Ex) http://restapi.example.com/houses/apartments/ (X)
  3. 하이픈(- )은 URI 가독성을 높이는데 사용

    • 불가피하게 긴 URI경로를 사용하게 된다면 하이픈을 사용해 가독성을 높인다.
  4. 밑줄(_ )은 URI에 사용하지 않는다.

    • 밑줄은 보기 어렵거나 밑줄 때문에 문자가 가려지기도 하므로 가독성을 위해 밑줄은 사용하지 않는다.
  5. URI 경로에는 소문자가 적합하다.

    • URI 경로에 대문자 사용은 피하도록 한다.
    • RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문이다.
  6. 파일확장자는 URI에 포함하지 않는다.

    • REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI 안에 포함시키지 않는다.
    • Accept header를 사용한다.
      Ex) http://restapi.example.com/members/soccer/345/photo.jpg (X)
      Ex) GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg (O)
  7. 리소스 간에는 연관 관계가 있는 경우 다음과 같이 표현한다.

    • /리소스명/리소스 ID/관계가 있는 다른 리소스명
    • Ex) GET : /users/{userid}/devices (일반적으로 소유 ‘has’의 관계를 표현할 때)
  8. 자원을 표현하는 컬렉션(Collection)과 도큐먼트(Document)

    • 위에 적힌 것처럼 컬렉션은 객체의 집합, 도큐먼트는 객체라고 생각하면 된다. 컬렉션과 도큐먼트 모두 리소스로 표현할 수 있으며 URI로 표현할 수 있다.
    • EX) http://edwith.org/courses/1
    • 위 경로에서 courses는 컬렉션을 나타내므로 복수로 표현해야 한다. courses/1 은 courses중에서 id가 1인 도큐먼트를 의미한다.

REST API 설계 예시

특징 및 장단점

특징

RESTful한 API를 구현하는 근본적인 목적이 성능 향상에 있는 것이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높이는 것이 주 동기이니, 성능이 중요한 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다.

장점

  • REST는 HTTP 표준을 기반으로 구현하므로, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있다.
  • 균일한 인터페이스를 사용하므로 클라이언트와 서비스 구현을 분리하는 데 도움이 된다.
  • 사내 시스템들도 REST 기반으로 시스템을 분산해 확장성과 재사용성을 높여 유지보수 및 운용을 편리하게 할 수 있다.
  • API를 Open API로 제공하기가 쉽다.
  • 멀티 플랫폼 지원 및 연동이 용이하다.
  • 원하는 타입으로 데이터를 주고받을 수 있다.
  • 기존의 웹 인프라(HTTP 기반의 웹)를 그대로 사용할 수 있다.(방화벽, 장비 요건 불필요)
  • 세션을 사용하지 않는다. 각각의 요청에 독립적.

단점

  • 분산 환경에는 부적합하다.
  • HTTP 통신 모델에 대해서만 지원한다.

(HTTP 응답상태코드)

1xx : 전송 프로토콜 수준의 정보 교환
2xx : 클라어인트 요청이 성공적으로 수행됨
3xx : 클라이언트는 요청을 완료하기 위해 추가적인 행동을 취해야 함
4xx : 클라이언트의 잘못된 요청
5xx : 서버쪽 오류로 인한 상태코드


package.json

node.js를 사용하며 패키지를 다운받으면 자동으로 package.json이라는 파일이 생기고, 어떠한 패키지들이 다운되었는지 적혀있었다. 이 package.json이라는 것에 대해 좀 더 자세히 알아보자.

package.json이란?

  • 프로젝트 정보와 의존성(dependencies)을 관리하는 파일이다. 이미 작성된 package.json 문서는 어느 곳에서도 동일한 개발 환경을 구축할 수 있게 해준다.
  • JSON 포맷으로 작성해야 하며, 다양한 옵션들이 추가될 수 있다.
  • 일반적으로 루프 디렉토리에 위치한다.
  • 프로젝트 정보 입력 시 필수로 입력되어야 하는 항목은 "name"과 "version"이다.
    • "name"에는 현재 패키지프로젝트(package.json)의 이름을 적는다.
      몇 가지 규칙이 있다.

      • name은 반드시 214자보다 짧아야 한다.
      • name은 점(.)이나 밑줄(_)로 시작할 수 없다.
      • name은 대문자를 포함해서는 안된다.
      • name은 URL의 일부분이자, 커맨드라인의 인수이고 폴더명이다. 따라서 모든 URL-safe하지 않은 name은 거부된다.
    • "version"은 현재 패키지의 버전을 적는다.

      • name과 version을 통해 고유성을 판별하게 된다. 따라서 패키지의 내용을 변경하려면 version을 변경해야만 한다.(배포가 아니면 크게 신경쓰지 않아도 될 듯 하다.)
      • version도 마찬가지로 규칙이 있다.
      • 우선은 SemVer로 분석 가능한 형태여야 한다.
      • 형태는 [메이저].[마이너].[패치] 3단계로 구성된다.

      • 틸트(~)와 캐럿(^) 등의 기호(version range)가 버전 앞에 붙는다.
        • 틸트(~)는 패치버전까지 변경을 허용한다.
          • 예시 : ~1.5.3는 1.5.8은 허용하지만 1.6.0은 허용하지 않는다.
        • 캐럿(^)은 마이너버전까지 변경을 허용한다.
          • 예시 : ^1.5.3은 1.8.7은 허용하지만 2.0.0은 허용하지 않는다.
        • npm은 캐럿(^)을 기본값으로 두고 있다.
      • npm에서 특정 버전을 설치하고 싶다면 npm install [패키지명]@버전하면 된다.
  • 필수로 입력되는 name과 server 외에 keywords, description, main, scripts, bugs, repository 등 다양한 정보를 제공할 수 있다.(npm init 명령어로 package.json 파일을 처음 작성하면 기본적인 옵션들을 작성할 수 있다.)
  • 의존중인 패키지들의 버전을 크게 두 가지 종류로 기록해준다.
    • dependencies
      • 프로덕션 환경에서 응용 프로그램에 필요한 패키지들이다. 배포할 때 포함된다.
    • devDependencies
      • 개발 또는 테스트 할 때만 의존한다. 배포할 때는 포함되지 않는다.

패키지와 모듈

  • 패키지
    • package.json으로 설명되는 파일 또는 디렉토리
    • npm 레지스트리에 공개되기 위해 반드시 package.json 파일을 갖고 있어야 한다.
  • 모듈
    • 모듈이 패키지보다 조금 더 큰 개념이다.
    • node.js의 require()함수로 로드될 수 있는 node_modules 디렉토리안의 파일 또는 디렉토리이다.
    • 주의 : 모듈은 package.json파일을 가질 필요가 없다. 모든 모듈이 패키지는 아니다. package.json을 가진 모듈만이 패키지이다.

참고자료

profile
공부

0개의 댓글