1 of 66

당신이 만든 건 REST가 아니지만

괜찮아

주영익 (youngiggy@gmail.com)

2 of 66

이 모든 것의 시작

3 of 66

발단

  1. 재미있는 글을 발견함

4 of 66

발단

5 of 66

발단

6 of 66

발단

7 of 66

HTTP

완벽가이드

  • 다시 도저언
  • 긴 싸움이 되겠군
  • 혼자는 외롭지
  • 릴레이 세미나

8 of 66

나는 API 서버를 제대로 구현해 본 적이 있던가?

9 of 66

API Design

개인 프로젝트

  • API 서버를 제대로 구현해보자
  • 그 과정을 블로그에 남기자
  • RESTful API 구현
  • GraphQL과의 비교
  • 여러가지 인증 방식 경험

10 of 66

정말 조금만 살펴보고 코딩을 시작하려고 했다

11 of 66

REST

12 of 66

REpresentational State

Transfer

13 of 66

Representation?

  • 어떤 리소스의 특정 시점의 상태를 반영하고 있는 정보
  • 내용 협상(Content negotiation)을 통해 선택됨
    • Content-Type: text/plain
    • Content-Language: ko

14 of 66

REST

15 of 66

효율적이고 확장성있는 시스템

16 of 66

Deriving REST

6 Constraints

  1. Starting with the Null Style
  2. Client-Server
  3. Stateless
  4. Cache
  5. Uniform Interface
  6. Layered System
  7. Code-On-Demand

17 of 66

Client-Server

  • Client-Server 구조
    • Client가 요청을 발생
  • 관심사의 분리
    • UI - Data storage 분리
  • 독립적인 진화

18 of 66

Stateless

  • No session state on server
  • Server가 요청을 이해하는데 필요한 모든 정보는 요청 안에 담겨 있어야 한다
  • 가시성, 신뢰성, 확장성

19 of 66

Cache

  • Cache할 수 있는지, 없는지 나타내기

20 of 66

Uniform Interface

  • 구성 요소간 균일한 인터페이스
  • 4 Interface Constraints
    • identification of resources
    • manipulation of resources through representations
    • self-descriptive messages
    • hypermedia as the engine of application state

21 of 66

Uniform Interface

4 Interface Constraints

  • Identification of resources
    • 일관된 자원 식별 방법
    • Resource == anything

22 of 66

Uniform Interface

4 Interface Constraints

  • Manipulation of resources through representation
    • 자원의 추상적 정의
      • Cool URIs don’t change
    • 리소스의 표현을 식별자로부터 분리함
    • 동일한 URI에서 동일한 자원에 대한 표현을 둘 이상 지원 가능

23 of 66

Uniform Interface

4 Interface Constraints

  • Self-descriptive messages
    • 요청이나 응답 메시지에는 이를 이해하기 위한 모든 정보가 포함되어야 한다

24 of 66

Uniform Interface

4 Interface Constraints

  • Hypermedia as the engine of application state
    • 다음 액션에 대한 선택지를 클라이언트에게 줘야한다
    • Out-of-band 정보 없이 client가 주도할 수 있는 충분한 힌트
    • 위대한 WWW를 보라

25 of 66

Layered System

  • 미들웨어 구성요소를 추가할 수 있는 구조
  • Server-Client 간 상호 작용을 일관성있게 유지해야 함
    • 중간에 구성요소가 추가됐는지, 다른 서비스와 추가로 통신하는지 관심없음

26 of 66

Code-On-Demand (Optional)

  • Script 등 추가 다운로드/실행을 통한 기능 확장
  • 따라서 가시성을 떨어뜨림
  • 따라서 Optional

27 of 66

Anti-REST

28 of 66

Anti-REST

  • 재미있는 글을 발견함
    • RESTful APIs, the big lie

29 of 66

Anti-REST

  • 재미있는 글을 발견함
    • RESTful APIs, the big lie
  • “그래, 공감이 되네”

30 of 66

Anti-REST

  • 재미있는 글을 발견함
    • RESTful APIs, the big lie
  • “그래, 공감이 되네”
  • 댓글을 읽기 시작
    • “그건 REST가 아니지”
    • “REST가 아니지가 아니지”
    • 풍부한 개싸움

31 of 66

Myths

32 of 66

미신 : REST는 4가지 HTTP 메소드를 쓰는 것

첫째, HTTP 메소드는

조회 = GET / 등록 = POST / 수정 = PUT / 삭제 = DELETE

와 같이 매핑되지 않는다.

이건 REST 문제가 아니라 HTTP의 문제.

33 of 66

미신 : REST는 4가지 HTTP 메소드를 쓰는 것

둘째, REST에서는 클라이언트가 어떤 메소드로든 시도할 수 있다.

서버가 어떤 메소드를 지원하는지 알아야 한다면 이는 out-of-band 정보이며,

RESTful하지 않다.

서비스하지 않는 메소드로 요청이 왔을 때, 서버는 405 Method Not Allowed를 리턴하면 된다.

34 of 66

미신 : REST는 4가지 HTTP 메소드를 쓰는 것

셋째, REST는 사실 HTTP에 종속되어 있지도 않다.

웹에서의 주요 프로토콜이 HTTP이고, 여기에 많은 영향을 많이 받았지만,

REST는 HTTP에 한정되지 않는다. (5.3.2 Connector View 참고)

사용하는 프로토콜 표준을 잘 지키는 것이 핵심.

35 of 66

미신 : REST는 좋은 URL에 관한 것이다

RESTful한 URI같은 건 없다.

/v1, /v2... 버저닝 필요없다.

  • 기억 나시죠? Cool URIs don’t change
  • 버저닝이 필요하시다고요? Hypertext를 제공하지 않나요?

36 of 66

미신 : REST는 좋은 URL에 관한 것이다

RESTful한 URI같은 건 없다.

/class/A/student/123/study-hard… depth를 구성할 필요없다.

  • 계층 정보를 몰라도 hypertext를 통해 리소스를 찾아가는 것이 좋다
  • URI 템플릿을 제공하는 방법도 있다
  • 클라이언트가 다음 행동을 결정하기 위한 충분한 정보를 제공하자

37 of 66

왜 그 훌륭한 개발자들이

오해를 하고 있을까?

38 of 66

ROA

39 of 66

Resource-Oriented Architecture

ROA는 REST 기반 웹서비스를 만들기 위한 문제점을 해결하는 방법을 제공한다.

ROA는 RESTful 아키텍처이다.

40 of 66

ROA

  • RESTful Web Services
    • Leonard Richardson
    • 한국번역서는 절판
  • Richardson Maturity Model
    • Martin Fowler의 소개글
    • 지앤선의 번역글

41 of 66

REST가 잘못 이해되었다는 건 알겠는데 이제 어떡하지?

42 of 66

REST에 대한 진실을 알아버린 당신의 선택은?

1. 못 본 척한다

  • 포기.하면.편하다
  • 꼰대란 소릴 듣지 않아도 된다
  • 어떤 것을 REST가 아니라고 설득하기엔 너무 많은 노력이 필요하다

43 of 66

로이 필딩이 면접에서 REST에 관한 질문을 받는다면?

그건 REST가 아니야

됐어

넌 탈락이야

44 of 66

REST

45 of 66

REST에 대한 진실을 알아버린 당신의 선택은?

2. RESTful하지 않으면 REST라고 부르지 않는다

  • 어렵지만 완벽한 해결책
  • REST란 용어를 잘못 이해하고 사용하면 커뮤니케이션에 방해가 된다
    • 하지만 제대로 알고 사용해도 (현실적으로) 커뮤니케이션이 안 되긴 마찬가지
  • 용기를 갖자고요

46 of 66

당신이 만든 건 REST가 아니지만 괜찮아

47 of 66

Your API isn’t RESTful

  • ...And That’s Good
  • A New Name, An Old Concept
  • 우리가 원하는 그것을 RESOURCEful API라고 부르자

48 of 66

Your API isn’t RESTful — And That’s Good

사람들은 SOAP 같은 프로토콜 대신 간단하고 표준적인 대안을 원했다.

REST의 아이디어 중 일부는 필요에 잘 부합했지만 전부는 아니었다.

그래서 사람들은 필요한 것을 가져갔고 나머지는 무시했다.

그들은 REST란 용어를 납치했다.

49 of 66

Your API isn’t RESTful — And That’s Good

REST라면 서버와 클라이언트가 강하게 결합하지 않아야만 한다.

클라이언트는 서버가 제공하는 하이퍼미디어를 탐색하는 방법만 이해하면 된다.

가장 일반적인 예는 월드 와이드 웹이다.

많은 웹 API는 클라이언트와 강하게 결합되어 있고 하이퍼미디어가 부족하기 때문에 REST의 원칙을 위반한다.

50 of 66

Your API isn’t RESTful — And That’s Good

우리에게 필요한 건 웹 API의 일반적인 사용 사례를 공식적으로 정의하고 표준화 하기.

이 모든 혼란을 종식하기 위해 그 개념을 새로 명명해야한다.

이를 통해 강력한 표준 및 모범 사례를 구축할 수 있다.

51 of 66

RESOURCEful API

52 of 66

약 파는 거

맞습니다

53 of 66

RESOURCEful API

다음의 조건을 만족할 때 RESOURCEful하다고 간주된다

  • API는 HTTP를 전송 레이어로 사용해야만 한다 (MUST)

  • 모든 API 엔드 포인트(URL)은 명사로 구성되어야 한다

  • 컬렉션에 속한 리소스는 컬렉션 URL을 접두어로 한다

  • API 버전 및 리소스 식별 매개 변수는 URL 경로에 있어야 한다

54 of 66

RESOURCEful API

다음의 조건을 만족할 때 RESOURCEful하다고 간주된다

  • 동작을 나타내는 API는 그 동작 자체를 명사로 나타내야 하며, 이때 HTTP 메소드는 POST를 사용한다

  • 구현된 HTTP 메소드는 HTTP Method spec에 따라 정의된 목적으로 사용되어야 한다

  • 구현된 HTTP 메소드는 안전함(Safe)과 멱등성(Idempotent) 원칙을 준수해야 한다

55 of 66

RESOURCEful API

다음의 조건을 만족할 때 RESOURCEful하다고 간주된다

  • HTTP 상태코드는 정의된 용도에 따라 모든 응답에서 사용되어야 한다

  • 200은 다른 가능한 상태코드가 있을 지라도 모든 성공적인 요청 결과의 응답 코드로 사용될 수 있다

  • 요청이나 응답의 본문의 형식은 Content-Type 헤더로 지정해야 한다

56 of 66

RESOURCEful API

다음의 조건을 만족할 때 RESOURCEful하다고 간주된다

  • API가 요청 본문의 형식을 지원하지 않으면 415(Unsupported Media Type) 상태를 반환해야 한다

  • 응답 본문의 형식은 가능하다면 Accept 헤더에서 요청한 형식이어야 한다

  • API가 요청 본문의 형식을 지원하지 않으면 406(Not Acceptable) 상태를 반환해야 한다

57 of 66

RESOURCEful API

추가로 우수 사례(best practice)로써 제안하는 것

  • URL을 소문자로 만들기

  • 특정 HTTP 메소드나 상태코드를 지원하지 않는 client를 위한 대체 수단을 만들기

  • JSON 형식은 항상 지원할 것

  • 항상 HTTPS를 통해 호스팅할 것

  • API가 새로운 리소스를 생성할 때는 응답 어딘가에 해당 자원의 식별자를 반환해야 함

58 of 66

안정적인 API를 위해 지켜야 할 것

Client

  • URI 구조에 의존하지 말 것
  • 새로운 링크에 대해선 열려있어야 하고
  • 모르는 필드가 추가됐다면 그냥 무시
  • API는 변화하기 마련

Server

  • 의미 없이 URI 구조를 무너뜨리지 말 것
  • 추가 리소스를 통해 진화하라
  • 오래된 양식을 지원하라

59 of 66

Laravel Controllers V5.2

60 of 66

Laravel Controllers V5.3

  • RESTful Resource Controllers

61 of 66

당신이 만든 건 REST가 아니지만 괜찮아

62 of 66

당신이 만든 걸 REST라고 안 부르면 괜찮아

63 of 66

하지만

우리

싸우지 말아요

64 of 66

선풍기 사망설

  • 잘 모르겠지만 검증하긴 어렵다
  • 텔레비전에 누가 나와서 틀고 자면 죽는다고 했다
  • 검증하기 귀찮은데 죽기도 싫다
  • 얼마나 많은 과학 ‘상식’이 거짓으로 밝혀졌는가?
  • 선풍기 사망설을 믿으면 똥멍청이인가?

65 of 66

압존법

  • 저는 압존법 모범생이었습니다
    • Since 국딩 ~ 2016년 겨울
  • 여러분 압존법 쓰지 마세요
  • 표준화법해설(1992)
    • “가정 내에서도 압존법을 지켜도 되고 안 지켜도 된다.”
  • 표준 언어 예절 - 경어법(2011)
    • “...직장에서 쓰는 것은 어색하다”

66 of 66

Q&A