rest api 개념 및 설계

REST

  • REST는 웹의 창시자(HTTP) 중의 한 사람인 Roy Fielding의 2000년 논문에 의해서 소개되었다. 현재의 아키텍쳐가 웹의 본래 설계의 우수성을 많이 사용하지 못하고 있다고 판단했기 때문에, 웹의 장점을 최대한 활용할 수 있는 네트워크 기반의 아키텍쳐를 소개했는데 그것이 바로 Representational State transfer (REST)이다.

REST 의 기본

  • rest는 요소로는 크게 리소스, 메서드, 메세지 3가지 요소로 구성된다. 예를 들어 이름이 Wonwoo인 사용자를 생성한다. 라는 호출이 있을 때 사용자는 생성 되는 리소스, 생성한다라는 행위는 메서드 그리고 이름이 Wonwoo인 사용자는 메세지가 된다. 이를 표현해보면
HTTP POST, http://localhost/users/
{
   "users" :{
       "name" : "Wonwoo" 
   }
}

와 같이 표현되며 생성한다는 의미를 갖는 메서드는 POST, 생성하고자 하는 대상이 되는 사용자라는 리소스는 http://localhost/users/라는 형태의 URL로 표현되며, 생성하고자 하는 사용자의 내용은 JSON 문서를 이용한다.

HTTP 메서드

메서드 의미
POST Create
GET Select
PUT Update
DELETE Delete
PATCH Update
  • 각각의 Post, Get, Put, Delete는 각각의 CRUD 메서드와 대응 된다.
  • Patch 라는 메서드는 Put과 동일한 의미이지만 Put은 해당자원을 전체 Update하라는 의미를 지닌 대신 Patch는 일부만 변경하겠다는 의미를 갖고 있다. 최근에는 Put보다 더 의미적으로 적합하다고 평가받고 있다.

REST의 리소스

  • Rest는 리소스 지향 아키텍쳐 스타일이라는 정의 답게 ㅗ든 것을 리소스 즉 명사로 표현을 하며, 각 세부 리소스에는 id를 붙인다. 즉 사용자라는 리소스 타입을 http://localhost/users 라고 정의했다면 Wonwoo라는 id를 갖는 리소스는 http://localhost/users/Wonwoo 라는 형태로 정의한다.
  • 예제로 통해 알아보자
    1. 사용자 생성

    • 다음은 http://localhost/users 라는 리소스로 이름은 wonwoo, 주소는 seongnam 이라는 내용을 이용해서 생성하는 표현이다.
HTTP Post, http://localhost/users
{
  "name" : "wonwoo",
  "address" : "seongnam"
}

2. 사용자 조회
– 다음은 생성된 리소스 중에서 http://localhost/users 라는 사용자 리소스중에, id가 wonwoo인 사용자 정보를 조회해오는 표현이다.

HTTP Get, http://localhost/users

3. 사용자 업데이트
– 다음은 생성된 리소스 중에서 http://localhost/users 라는 사용자 리소스중에 id가 wonwoo인 사용자정보에 대해 주소를 seoul으로 수정하는 표현이다.

HTTP PUT, http://localhost/users/wonwoo
{
  "address":"seoul"
}

4. 사용자 삭제
– 다음은 생성된 리소스 중에서 http://localhost/users 라는 사용자 리소스중에 id가 wonwoo인 사용자 정보를 삭제 하는 표현이다.

HTTP DELETE, http://localhost/users/wonwoo
  • 간단하게 CURD 표현이 끝났다.

REST의 특성

  1. 유니폼 인터페이스(Uniform Interface)
    • REST는 HTTP 표준에만 따른 다면, 어떠한 기술이라던지 사용이 가능한 인터페이스 스타일이다. HTTP + JSON으로 정의를 했다면, 안드로이드건, IOS건, C 기타 다른 언어에 종속 받지 않고 사용할 수 있는 느슨한 결함 형태의 구조다.
  2. 무상태성/스테이트리스(Stateless)
    • REST는 Representational State Transfer의 약어로 상태를 유지하지 않는 특징 중 하나이다. 상태가 있다 없다의 의미는 사용자나 클라이언트의 컨택스트를 서버쪽에 유지 하지 않는다는 의미로 HTTP Session과 같은 상태 정보를 저장하지 않으며 각 API 서버는 들어오는 요청만 메시지로 처리하면 된다.
  3. 캐싱(Cacheable)
    • REST의 큰 특징 중 하나는 기존의 HTTP라는 웹 표준을 그대로 사용하기 때문에 웹에서 사용하는 기존의 인프라를 그대로 활용이 가능하다. HTTP 기반의 로드 밸런서나 SSL은 물론이고 캐싱기능을 적용할 수 있다. 일반적인 서버등의 캐싱하는 것은 용량이나 성능 면에서 많은 장점을 가지고 올 수 있다. 구현은 HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-TAG를 이용하면 캐싱을 구현 할 수 있다. Client가 HTTP GET을 Last-Modified 값과 함께 보냈을 때, 컨텐츠가 변화가 없으면 Rest 컴포넌트는 304 Not modified를 리턴하면 Client는 자체 캐쉬에 저장된 값을 사용하면 된다.
  4. 자체 표현 구조(Self-descriptiveness)
    • REST API 자체가 매우 쉬워서 API 메시지 자체만 보고도 API를 이해할 수 있는 Self-descriptiveness 구조를 갖는다. 리소스와 메서드를 이용해서 어떤 메서드에 무슨 행위를 하는지를 알 수 있으며, 또한 메시지 포맷 역시 JSON을 이용해서 직관적으로 이해가 가능한 구조이다.
  5. 클라이언트 서버 구조(Client-Server 구조)
    • 근래에 들면서 재 정립되고 있는 특징 중의 하나는 REST가 클라이언트 서버 구조라는 것이다. REST 서버는 API를 제공하고 제공된 API를 이용해서 비즈니스 로직 처리 및 저장을 책임진다. 클라이언트 경우 사용자 인증이나 컨텍스트(세션, 로그인정보) 등을 직접 관리하고 책임지는 구조로 역할이 나뉘어 지고 있다. 이렇게 역할이 각각 확실하게 구분되면서, 개발관점에서 클라이언트와 서버에서 개발해야 할 내용들이 명확하게 되고 의존성도 줄어든다.
  6. 계층형 구조(Layered System)
    • 계층형 아키텍쳐 구조 역시 근래에 들어서 주목받기 시작하는 구조 인데 클라이언트 입장에서는 REST API만 호출 한다. 그러나 서버는 다중 계층으로 구성될 수 있다. 순수 비즈니스 로직을 수행하는 API 서버와 그 앞 단에 사용자인증(Authentication), 암호화(SSL), 로드밸런싱등을 하는 계층을 추가해서 구조상의 유연성을 둘 수 있는데 이는 근래에 들어서 마이크로 서비스 아키텍쳐의 api gate나 간단한 기능의 경우는 HAProxy나 Apache와 같은 Reverse Proxy를 이용해서 구현하는 경우도 있다.

REST 안티 패턴

1. GET/POST를 이용한 터널링
– http://localhost/users?method=update&id=wonwoo 이 경우가 전형적인 GET을 이용한 터널링이다. 메서드의 실제 동작은 리소스를 업데이트 하는 내용인데, HTTP PUT이나 PATCH를 사용하지 않고 쿼리파라미터로 method=update라고 넘겨서 수정 메서드임을 명시했다. 또 한 Insert성 오퍼레이션이 아닌데도 불구하고 JSON 바디에 오퍼레이션명을 넘기는 형태인데 예를 들어 특정 사용자 정보를 가지고 오는 API를 아래와 같이 POST를 이용해서 만든 경우이다.

HTTP POST, http://localhost/users
{
  "getuser": {
     "id" : "wonwoo"
  }
}

2. HTTP Response code를 사용하지 않음
– 다음으로 많이 하는 디자인 중 하나가 Http Response code를 충실하게 따르지 않고 성공은 200, 실패는 500과 같이 1~2개의 Http Response code만 사용하는 경우이다. 심한 경우에는 에러도 Http Response code 200으로 정의한후 별도의 에러 메시지를 200 Response code와 함께 보내는 경우이다.

출처: 조대협님 블로그(http://bcho.tistory.com/m/post/953)

Accept와 Content-type

Accept

  • 클라이언트가 서버에 어떤 형식(MediaType)으로 달라는 요청을 할 수 있는데 이게 Accpet 헤더를 뜻하는거다.

Content-Type

  • 클라이언트가 request에 실어 보내는 데이타(body)의 형식(MediaType)를 표현하는거다.

jvm 가비지 컬렉션

가비지 컬렉션(이하 GC)

GC 의 과정

  • GC에 대해서 알아보기전 알아야 용어가 있다. 바로 stop-the-world이다. stop-the-world란 GC를 실행하기 위해 JVM이 어플리케이션 실행을 멈추는 것이다. stop-the-world가 발생하면 GC를 실행하는 쓰레드를 제외한 나머지 쓰레드는 모두 작업을 멈춘다.
    대게의 경우 GC 튜닝이란 이 stop-the-world 시간을 줄이는 것이다.

  • 자바는 프로그램 코드에서 메모리를 명시적으로 해제하지 않는다. 가끔 명시적으로 해제하려고 해당 객체를 null로 지정하거나 System.gc() 메서드를 호출하는 개발자가 있다. null로 지정하는 것은 큰 문제가 안되지만 System.gc() 메서드를 호출하는 것은 시스템의 성능에 큰 영향을 끼치므로 자제 해야 된다.

  • 오라클의 HotSpot VM에서는 크게 2개의 물리적 공간으로 나뉜다. Young 영역Old 영역이다.

    1. Young 영역(Yong Generation 영역)

    • 새롭게 생성한 객체의 대부분이 여기에 위치한다. 대부분의 객체가 금방 접근 불가능 상태가 되기 때문에 많은 객체가 여기서 생성되었다가 사라진다. 이 영역에서 객체가 사라질 때 Minor GC가 발생한다고 한다.
      2. Old 영역(Old Generation 영역)
    • 접근 불가능 상태로 되지 않아 Young 영역에서 살아남은 객체가 여기로 복사된다. 대부분 Young 영역보다 크게 할당되며, 크기가 큰 만큼 Young 영역보다 GC는 적게 발생한다. 이 영역에서 객체가 사라질 때 Major GC(혹은 Full GC)가 발생한다고 한다.
  • 위 그림의 Permanent Generation 영역(이하 Perm 영역)은 Method Area라고도 한다. 객체나 억류(intern)된 문자열 정보를 저장하는 곳이며, Old 영역에서 살아남은 객체가 영원히 남아 있는 곳은 절대 아니다. 이 영역에서 GC가 발생할 수도 있는데 여기서 GC가 발생해도 Major GC의 횟수에 포함된다.

Young 영역의 구성

  • Young 영역은 3개의 영역으로 나뉜다.
    1. Eden 영역
    2. Survivor 영역(2개)
  • Survivor 영역이 2개이기 때문에 총 3개의 영역으로 나뉜다. 각 영역의 처리 절차 순서를 기술하면 다음과 같다.

    1. 새로 생성한 대부분의 객체는 Eden 영역에 위치한다.
    2. Eden 영역에서 GC가 한번 발생한 후 살아남은 객체는 Survivor 영역 중 하나로 이동된다.
    3. Eden 영역에서 GC가 발생하면 이미 살아남은 객체가 존재하는 Survivor 영역으로 객체가 계속 쌓인다.
    4. 하나의 Survivor 영역이 가득차게 되면 그 중에서 살아남은 객체를 다른 Survivor 영역으로 이동한다. 그리고 가득 찬 Survivor 영역은 아무 데이터도 없는 상태로 만든다.
    5. 이 과정은 반복하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동하게 된다.
  • 이 절차를 확인해 보면 알겠지만 Survivor 영역 중 하나는 반드시 비어 있는 상태로 남아 있어야 한다. 만약 두 Survivor 영역에 모두 데이터가 존재하거나, 두 영역 모두 사용량이 0이라면 정상적인 상황이 아니라고 생각된다.

  • Eden 영역에 최초로 객체가 만들어지고, Survivor 영역을 통해서 Old 영역으로 오래 살아남은 객체가 이동한다는 사실은 꼭 기억하자!!

출처 : hello naver(http://d2.naver.com/helloworld/1329)