웹을 지탱하는 기술 스터디 1회차

‘웹을 지탱하는 기술’ 1회차

목적

첫번째 목적

HTTP와 URI, 그리고 각종 하이퍼미디어의 포멧의 스펙을 설명하는 것이다. 스펙을 안다는 것은 좋은 웹서비스의 설계로 향하는 첫걸음이기 때문입니다. 하지만, 스펙을 안다고해서 좋은 설계를 할 수 있는것은 아닙니다. 웹다움은 그런 스펙들이 가진 아키텍처적인 뒷받침에 기초하고 있기 때문입니다. 우리는 HTTP나 URI가 왜 이런 스펙을 가지게 되었는지, 웹 아키텍처의 관점에서 잘 알아야합니다.

두번째 목적

웹 서비스의 구체적인 설계방법을 아는것 설계란 시스템 전체의 밸런스를 잡는 작업이다. 하지만 시스템 전체에 대한 깊은 지식이 필요하므로 우선 좋은 설계란 무엇인가 알아보고 구체적인 웹 서비스를 제재로 설계 프로세스의 사고방법을 알아보도록 해야합니다.

제 1부

웹이란 무엇인가?

웹의 용도를 3가지로 나눌수있다.

  • 웹사이트
  • 유저 인터페이스(UI)
  • API

웹을 지탱하는 가장 근본적인 기술은 HTTP와 URI, 그리고 HTML입니다. URI를 사용해 어느 특정 사이트의 다양한 정보를 가리킬수있다. HTML은 그 정보를 표현하는 문서형식이다. 그리고 HTTP라는 프로토콜을 사용해 그정보들을 가져오거나 내보낼 수 있다. 이 기술 3가지는 매우 심플하다.

ex)

  • URI : 종이 광고에 삽입할 수 있을 정도의 짧은 문자열
  • HTML : XML을 바탕으로 한 범용 문서포맷
  • HTTP : 적은 8개의 메소드를 가졌다.

위 3가지가 지탱하고 있는 웹을 정보시스템으로 본다면

  • 하이퍼미디어 : 텍스트, 이미지, 음성, 영상 등 다양한 미디어를 하이퍼링크로 연결해 구상한 시스템이다. 책이나 영화와는 반대로 비선형적으로 사용자가 스스로 링크를 선택해 원하는 정보를 얻는다.
  • 분산 시스템 : 복수의 컴퓨터를 조합해 처리를 분산시키는 형식 특징은 프로토콜이 심플하다.

이라는 2가지 측면으로 볼 수 있다.

웹의 역사

Chapter03

REST 웹의 아키텍처 스타일

REST는 웹의 아키텍처 스타일입니다. 아키텍처 스타일은 ‘아키택처 패턴’ 이라고 하며, 복수의 아키텍처의 공통된 설질, 양식, 규정 혹은 독특한 방식을 가리키는 말입니다. ex) MVC, 파이프 앤 필터, 이벤트 시스템이 있다. 그 아키텍처를 설계할 때 설계 지침, 규정, 방식 즉, 스타일을 적용할때 필요한 나침반의 역할을 하는것.

REST는 수많은 아키텍처 스타일중 에서도, 특히 네트워크 시스템의 아키텍처 스타일이다. ex) 클라이언트/서버 순수한 클라이언트/서버 아키텍처 스타일에 몇가지 제약을 더하면 REST가 된다. 제약은 아키텍처 스타일에서 중요한 개념입니다. ex)

  • 아키텍처 스타일 : Rest
  • 아키텍처 : 브라우저, 서버, 프록시, HTTP, URI, HTML
  • 구현 : Apache, Firefox, Internet Explorer

리소스(Resource)

REST에 있어서 가장 중요한 요소들중 하나 리소스가 있다. ‘웹상에 존재하는 이름을 가진 모든 정보’를 리소스라 한다. 리소스의 이름으로 다른 리소스와 구별한다. 즉 리소스는 URI다.

정리

  • 리소스란 웹상의 정보이다.
  • 전 세계의 무수한 리소스는 각각 URI로 의미 있는 이름을 가진다.
  • URI를 이용함으로써, 프로그램은 리소스가 표현하는 정보에 접근할 수 있다.

리소스의 어드레스 가능성

URI는 구조를 가지고 있다 그렇기 때문에 프로그램에서 간단하게 처리할 수 있습니다. URI가 지니고 있는 리소스를 간단히 가리킬 수 있는 성질을 ‘어드레스 가능성’이라고 부릅니다.

복수의 URI를 가진 리소스

1개의 리소스는 복수의 URI를 가질 수 있다. 하나의 리소스에 여러 URI를 붙여 두면, 클라이언트가 리소스에 접긴하기 쉬워지나 어느 것이 정식 URI인지 알기 힘들다. 리소스는 ‘웹상에 존재하는 정보’라는 추상적인 개념이다. 서버와 클라이언트는 실제로 리소스를 주고 받을때 어떤 구체적인 데이터를 서로 송신하는데, 이 데이터를 ‘Resource Representation’이라고 한다. 또한 리소스는 복수의 표현을 가질 수 있고, ‘상태’라는 것이 존재하는데 시간의 경과에 따라 리소스의 상태가 변하면 그 표현도 변한다.

스타일을 조합하여 REST를 구성한다.

REST는 복수의 아키텍처 스타일을 조합하여 구축한 복합 아키텍처 스타일입니다.

클라이언트 서버

흔히 웹은 HTTP라는 프로토콜을 이용해 클라이언트와 서버가 서로 통신하는 클라이언트/서버의 아키텍처 스타일을 채용하고 있습니다. 즉 클라이언트에서 서버에 요청을 보내면 서버는 클라이언트에 대해 응답을 돌려줍니다.

스테인리스 서버

클라이언트/서버에 최초로 추가할 아키텍처 스타일은 스테인리스 서버이다. 스테인리스란, 클라이언트의 에플리케이션 상태를 서버에서 관리하지 않는다는 것을 의미한다. 하지만 다 지킬순 없다. 특히 HTTP를 스테이트풀하게 만드는 대표적인 것은 Cookie며, 사용을 할수밖에 없는것이 현실이다. 그러므로 최소한 이용하도록 해야한다. 클라이언트/서버에 스테인리스성을 도입하면 아키텍처 스타일은 ‘클라이언트/스테인리스 서버’가 된다.

캐시

캐시란, 리소스의 신선도에 기초해 한번 가져온 리소스를 클라이언트 쪽에서 돌려쓰는 방식이다.

  • 캐시의 장점 : 서버와 클라이언트 사이의 통신량을 줄여 네트워크 대역의 이용과 처리시간을 축소하고, 더욱 효율적으로 처리할 수 있다.
  • 단점: 오래된 캐시를 이용해 정보의 신뢰성이 떨어질 가능성이 있다.

캐시를 추가한 아키텍처 스타일은 ‘클라이언트/캐시/스테인리스 서버’ 라고합니다.

유니폼 인터페이스

유니폼 인터페이스는 URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일이다. 예를들어, HTTP 메서드가 8개로만 정의되어 있고, 보통은 이 이상 늘어나지 않는것처럼 유니폼 인터페이스는 REST를 가장 특징짓는 아키텍처 스타일이다.

유니폼 인터페이스를 추가한 아키텍처 스타일을 ‘유니폼/클라이언트/캐시/스테인리스 서버’ 라고한다. 또한, 유니폼 인터페이스는 시스템 전체를 계층화하기 쉽다. 시스템을 몇 개의 계층으로 분리하는 아키텍처 스타일을 계층화 시스템이라고 한다.

코드 온 디맨드

프로그램 코드를 서버에서 다운받아 클라이언트에서 실핸하는 아키텍처 스타일이다. ex) javaScript, Flash, Java 애플릿 등

  • 장점 : 클라이언트를 차후에 확장할 수 있다는 것.
  • 단점 : 네트워크 통신에서의 프로토콜 가시성이 저하된다.

결론

REST란 앞에 소개한 6가지를 조합한 아키텍처 스타일을 가리킨다.

  • 클라이언트/서버 : 유저 인터페이스와 처리를 분리한다.
  • 스테인리스 서버 : 서버 측에서 애플리케이션의 상태를 가지지 않는다.
  • 캐시 : 클라이언트와 서버의 통신횟수와 양을 감소시킨다.
  • 유니폼 인터페이스 : 인터페이스를 고정한다.
  • 계층화 시스템 : 시스템을 계층별로 분리한다.
  • 코드온 디맨드 : 프로그램을 클라이언트에 다운로드하여 실행한다.

상황에따라 다른 아키텍처 스타일을 채용할 수 있다. ex) P2P

REST의 2가지 측면

REST와 하이퍼 미디어

예를들어 소셜 북마크 서비스는 하이퍼미디어의 기본 기능인 링크를 따라가는 작업을 몇 번 거치면서 전체적으로는 소셜 북마크라는 하나의 애플리케이션이 실현된다. 웹이 가진 이 특징을 REST에서는 애플리케이션 상태 엔진으로서의 하이퍼미디어 라고한다. 애플리케이션 상태는 하이퍼 미디어의 링크를 따라가는 작업에 의해 변화하며, 이것이 하이퍼미디어가 애플리케이션 상태 엔진이라고 불리는 까닭이다.

REST의 의미

REST는 웹 전체의 아키텍처 스타일입니다. 우리들이 만드는 웹 서비스나 웹 API는 웹을 구성하는 일부분입니다. 개별 웹 서비스와 웹 API가 RESTFul이 되면, 웹은 전체적으로 더욱 좋아진다.

제 2부

URI

URI는 Uniform Resource Identifier의 약자로 ‘리소스를 통일적으로 식별하는 ID’를 말합니다.

URI는 다음과같이 나눌수있습니다.

http://yohei:pass@blog.example.com:8000/search?q=test&debug=true#n10

  • URI Scheme

    • http
    • URI가 이용하는 프로토콜을 나타낸다.
  • 사용자정보

    • yohei:pass
    • 이 리소스에 접글 할때 이용할 사용자의 정보
  • 호스트형

    • blog.example.com
    • DNS에서 이름을 해석할 수 있는 도메인명이나 IP어드레스
  • 포트번호

    • 8000
    • 호스트에 엑세스 할 때, 프로토콜이 사용하라 TCP의 포트번호
  • 패스

    • /search
    • 호스트 안에서 오직 하나의 리소스를 가리킬때 사용
  • 쿼리 파라미터

    • q=test&debug=true -검색 서비스에서 검색 키워드를 전달할 때 등 클라이언트에서 동적으로 URI를 생성할 때 사용
  • URI 프래그먼트

    • n10

    • 리소스 내부에서 더 세세한 부분을 특정할때 이용

절대URI와 상대 URI

  • 절대 URI

    • 파일 시스템에서는 루트에서부터 전체 경로를 기술한 것을 ‘절대 경로’라고 부른다.
    • http://example.com/foo/bar
  • 상대 URI

    • URI스키마와 호스트명을 생략하고, 경로만을 표현함
    • /foo/bar
  • Base URI

    • 기점이 되는 URI를 지정하는것
    • 보통 상대URI를 절대RUI로 변환함

URI와 문자

다음의 문자들을 URI의 경로에 사용할수있습니다.

  • 알파벳 : A-Za-z
  • 숫자 : 0~9
  • 기호 : -.~:@!$&’() 이 문자열을 소위 ASCII문자입니다. but 한글이나 일어등 문자를 넣을경우 %인코딩 방식을 이용한다.

요즘 많은 웹사이트에서 문자 인코딩으로 UTF-8을 채용하고 있기 때문에, URI를 UTF-8로 %인코딩하는 경우가 대부분이다.

URI의 설계

‘URI는 변하지 않아야 한다. 변하지 않는 URI야말로 최고의 URI다.’

변하지 않는 URI를 목적으로 이렇게 설계해 나갈 수 있다.

Point

  • URI에 프로그래밍 언어에 의존적인 확장자와 경로를 포함하지 않는다.
  • URI에 구현에 의존적인 경로명을 이용하지 않는다.
  • URI에 프로그래밍 언어의 메서드명을 이용하지 않는다.
  • URI에 세션ID를 포함하지 않는다.
어떤 리소스를 취득할지 갱신할지는 URI로 지정하는 것이 아니라, URI에 적용하는 HTTP 메서드로 결정한다. 따라서 URI는 전체적으로 명사가 되도록 설계해야한다.

URI의 사용성

구현 의존성을 배제하고 심플하게 만들면 URI가 쉽게 변경되지 않는다는 것을 강조했다. 심플한 URI는 사용성(Useability)이 향상된다. 기억하기 쉽고, 개발자가 아닌 보통 사람들도 사용하기 쉽다.

URI를 변경하고 싶을 때.

어떻게든 변경해야 할 때는 가능한 한 Redirect하도록 하자.

URI 설계의 테크닉

매트릭스 URI

  • 확장자로 표현을 지정한다
  • 구현에 의존하지 않는 확장자는 좋은 측면도 가지고 있는 경우가 있다.

    • 콘텐트 네고시에이션이란 기능으로 한국어판 OS를, 사용하는 유저에게는 한국어를 영어판을 사용하는 유저게엑는 영어를 반환해준다.

URI의 불투명성

심플한 URI는 가독성이 높기 때문에 사용자가 URI의 구조를 추측하기 쉬워진다.

URI의 내부구조를 상상해 조작하거나, 클라이언트쪽에서 URI를 구축해서는 안 된다. 왜냐하면 서버쪽에서 URI의 구조를 변경하는 순간 시스템이 동작하지 않게 되는, 이른바 ‘밀결합’ 상태가 되기때문이다. 이렇게 클라이언트 쪽에서 구성하거나 확장자로 리소스의 내용을 추단하거나 할 수 없는 특성을 ‘URI는 클라이언트에 있어 불투명하다’ 라고 합니다.

URI를 강하게 의식하기

  • URI는 리소스의 이름이다
  • URI는 수명이 길다.
  • URI는 브라우저가 어드레스 란에 표시한다.

이런 관점에서 URI는 웹 서비스와 웹 API의 설계에 있어서 가장 중요한 부분이라고 할 수 있다.