• [ 배경 ]
    • 중고거래 프로젝트를 진행하면서 API 구조 및 요청, 결과 데이터 설계에 대해 고민하였습니다.
    • Controller에 URL 패턴을 맵핑할 때 보다 효율적인 방식은 뭐가 있을까 고민하던 중 REST API 설계 패턴에 대해 알게 되었습니다.
    • Restful 한 api에 대해 알아보고 올바른 디자인 방법을 프로젝트에 적용시키려고 합니다.

    • REST 아키텍처
      • 웹(HTTP)의 공동 창시자 Roy Fielding이 2000년 박사 논문에 소개함.
      • 기존의 웹이 HTTP의 장점을 100% 활용하지 못함.
      • Google, Amazon에 의해 주도됨

REST 구성


  • [ 과정 ]
    • REST의 기본
      • 사용자라는 Resource ('http://localhost:8080/users/myInfo') URL을 통해 접속 후의
        사용자 정보를 Representation으로 보여주는 방식 (HTTP GET method)

HTTP 메서드

  • 리소스(자원)이란 URI로 자원 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고받는 모든 것을 의미한다.

  • 자원 은 해당 소프트웨어가 관리하는 모든 것을 의미하며, 예를 들면 DB안에 들어가 있는 데이터 하나하나, 이미지 하나하나 등을 의미할 수 있다. 

  • 상태의 전달은 데이터가 요청되는 시점에서 요청받은 자원의 상태(정보)를 전달하는 것을 의미하는데, 보통 JSON 형식이나 XML 형태를 이용하여 자원의 상태를 전달하게 한다.

  • REST란, HTTP URL을 통해 자원을 명시하고, HTTP Method(POST, GET, DELETE, PUT)을 통해 해장 자원에 대한 CRUD(CREATE, READ, UPDATE, DELETE 오퍼레이션을 적용하는 것 이이라고 할 수 있다.

  • REST의 특성
    • HTTP 표준만 따르면 어떠한 기술도 사용 가능하다 (HTTP/JSON, HTTP, XML)
    • 무상태성 (STATELESS)이다.
    • 캐싱이 가능하다.
      • 기존 웹 인프라를 그대로 사용한다.
      • 웹 캐시, CDN을 이용한 캐시 방식이 있다.
    • 자체 표현 구조 
      • API 내용만 보고도 별도의 문서 없이 쉽게 이해가 간다.
    • Layered System(계층화) Client에서는에서는 REST API Server 호출한다.
    • REST Server 다중계층으로 구성될  있다. API Server 순수 비즈니스 로직을 수행하고  앞단에 보안, 로드벨런싱로드 벨런싱, 암호화, 암호화 사용자사용자 인증 등을 추가하여 구조상의 유연성을   있다.
    • LB, 공유 캐시 등을 통해 확장성과 보안성을 향상할  있고 PROXY, 게이트웨이 같은 네트워크 기반 중간 매체를 사용하기 좋다.

  • REST API 단점
    • 명시적인 표준이 없다.
    • 관리가 어렵다.
    • 좋은 디자인을 가이드하기 어렵다.

  • RESTful 한 설계가 필요하다.
    • RDBMS는 관계형으로 리소스를 표현하지 않는다. REST 한 테이블 구조 설계가 필요하다.
    • JSON을 그대로 저장하는 도큐먼트 기반의 NoSQL이 잘 맞는다. (ex MongoDB)

  •  REST API 6가지 규약 조건 
    1. lient-server 간 확장성을 단순화, 서로 의존하지 않고 클라이언트는 서버의 URI만 알고 있게 하는 것이다.
    2. stateless 하기 때문에 클라이언트에서 서버로의 각 요청에는 그 요청을 이해하는 모든 정보가 포함되어야 한다. 
    3. cacheable 요청에 대한 응답 내의 데이터에 해당 요청은 캐시 가능 여부 명시해야 한다.
    4. uniform Interface 전체 시스템 아키텍처를 간단하고 잘 파악할 수 있도록 하기 위한 interface가 돼야 한다.  
    5. self-descriptive messages 자기 서술적 메시지 즉 어떤 메시지인지 알 수 있어야 한다.
    6. Layered System 각 구성들 간의 계층을 마음대로 상호작용 할 수 없도록 제한한다.

  • uniform Interface 관해 알아야 할 내용
    • HEATEOS(hypermedia as the engine of application state.)
      • 애플리케이션의 상태는 HyperLINK를 이용해 전이되어야 한다. (페이지 변경 등), 즉 링크가 동적으로 변경될 수 있음.

    • manipulation of resources through representations
      • 특정 시점의 리소스의 상태를 리소스 표현(Resource Representation)이라고 부릅니다. Resource Representation에는 데이터, 메타데이터 그리고 상태를 변경할 수 있는 하이퍼링크가 포함됩니다. 데이터 타입은 ContentType 헤더에 media-type을 사용하여 나타냅니다. (ContentType:application/json // 메타 데이터)

    • 하이퍼텍스트
      • 유저가 선택적으로 정보의 표현과 제어를 동시에 할 수 있는 방법이라고 표현합니다 
        이해할 수 있는 형식, 관계 타입을 갖추어 hypertext를 통한 link로 사용한다면 그것은 REST 하다고 할 수 있다고 합니다.

    • Resource Methods
      • 많은 사람들이 resource methods를 GET/PUT/POST/DELETE와 관련 있다고 생각합니다.  
        사실, 로이 필딩은 각 컨디션에 따라서 HTTP method를 맞춰 사용해야 한다고 한 적이 없고 uniform interface를 강조한 것이라고 합니다. 

  • Resource 이름 가이드
    • 만약 Naming 설계가 잘 이루어져 있다면 Client가 사용하기 쉬울 것이며, 그렇지 않다면 사용하기 쉽지 않을 수도 있습니다.
      • 동사가 아닌 명사로 Resource를 표현하라
        명사는 해당 Resource의 속성을 표현할 수 있지만 동사는 그렇지 못하기때문
      • 계층적 구조를 나타낼 때 /를 사용하라.
      • URI path의 제일 마지막에는 /를 사용하지 말라.
      • -를 이용하여 띄어쓰기를 대신하라. (cabab)
      • _를 사용하지 말라
      • 소문자를 사용하라.
      • file의 확장자를 사용하지 말라. 

  • Resource의 표현방식은 document, collection, store 그리고 controller 4가지로 나눌 수 있다고 합니다. 
    각 표현 방식에 대해서 한번 알아보도록 하겠습니다.
    • document는 1개의 개체를 나타내는 것
    • collection은 단일 Resource(document)들의 묶음입니다.
    • store는 client입장의 resource저장소입니다. 장바구니 같은 개념이라고 생가하시면 좋을 것 같습니다.  
      store URI는 API로 client가 resource를 넣고 빼고를 자유롭게 할 수 있게 합니다.  
      새로운 URI를 생성하지 않으며, 처음에 resource를 등록할 때 client가 전달한 key로 저장합니다. 복수의 형태를 사용합니다.
    • controller resource model은 절차적인 개념입니다. Body에서는 controller의 경우 resource를 조작하는 게 아닌 직접 function을 실행하는 것이기 때문에 이런 경우에는 동사를 사용해도 좋다고 합니다. 

  •  REST에서는 기본 데이터 표현을 Resource라고 하고 이러한 Resource의 요소에는 Data, metadata, link가 있다는 것을 알게 되었습니다.
    • Resource는 단건일 수 있고, 단 건의 집합일 수 있습니다.
    • Customer라고 하면 1명의 고객이 되며 이들의 집합은 customers는 손님 전체를 뜻 
      손님들 : /customers, 2번 ID를 가진 손님 : /customers/2
    • Resource는 서브 Resource를 포함할 수 있습니다. 
      손님들의 계좌를 관리한다면, 손님의 하위에 계좌를 포함할 수 있습니다. 
      2번 손님의 모든 계좌 : /customers/2/accounts, 2번 손님의 2번 계좌 : /cusotmers/2/accounts/2

  • 단수보다는 복수형을 사용해야 한다. EX) /dog(X) , /dogs(O)

  • 리소스 간의 관계 표현방법
    • 서브 URL을 사용하는 방법
      • GET /owners/{terry}/dogs
    • 관계를 표현하는 리소스를 별도로 정의하는 방법
      • GET /people/terry/ownsdog/puppy
    • 리소스 간 관계가 많지 않고 단순한 경우에는 첫 번째 방식을, 복잡한 경우 두 번째 방식을 사용.

  • 에러 처리

 

  • 버전 관리
    • 가급적이면 하위 호환성을 보장하는 게 좋음 (ex JSON의 스키마 리스)
    • API 버전 정의 법 
      • ex) facebook :? v=2.0  , Salesforce : /service/data/v2.0/subject/account
    • 추천 방법
      • api.server.com/{서비스명}/{버전}/{리소스}
      • ex) api.server.com/account/v2.0/groups
      • account1.war, account2.war로 새 버전을 별도의 배포 패키지로 관리하기가 편함.

  • 페이징

 

  • 부분 응답 (Partial Response)

  • API 보안
    • 인증 (API 키 방식, API 토큰 방식)
    • 인가 (사용자, 관리자를 부여하는 방식, 사용자별 각각 세부 권한을 부여 방식)
    • 네트워크 레벨 전송 암호화 (SSL)
    • 메시지 무결성 보장 (대칭키 알고리즘 특정 필드 암호화)
    • 메시지 Body 암호화 (HMAC)
  • API 보안엔 위 같은 내용이 있는데 추후 다른 글에서 자세히 정리할 예정입니다.
  • JWT 토큰을 이용해 JSON 상태 정보를 넣어서 서버 쪽의 상태 정보를 다루는 부담을 덜 수도 있습니다.
    권한 정보를 넣음으로써, 권한 처리에도 이용될 수 있습니다.


  • API 문서화

  • 중고거래 프로젝트에서 REST API를 적용 후 Swagger 화면


  • [ 결과 ]
    • URI는 자원 정보를 잘 표현하기 위해 동사보다는 명사를 사용하였고 단수보다는 복수형을 사 용하였습니다.
    • 자원 정보 관계 표현에는 HTTP method와 중복되는 내용은 제거하였습니다.
    • HttpStatus 공식문서를 전부 읽어보며 HTTP 응답 상태 코드에 적절한 값을 설정하였습니다.

  • [ 성과 ]
    • 일반 Appication에 REST API의 6원칙을 지킨다면 그 Application은 충분히 RESTful 하다고 할 수 있습니다.
      중고거래 프로젝트의 API 내용만 보고도 자원을 이름으로 구분하여 자원의 상태를 주고받는 모든 것을 별도의 문서 없이 쉽게 이해가 됐습니다.

 

junshock5/used-market-server

중고거래 프로젝트. Contribute to junshock5/used-market-server development by creating an account on GitHub.

github.com

+ Recent posts