그동안 BMT로 인하여 정신없이 보내어 본 '웹 2.x시대의 서버측 웹 개발 환경' 시리즈의 세번째 글이 늦어졌습니다.매일 꼬박꼬박 블로그에 글을 올리는 분들이 정말로 존경스럽습니다. 회사에선 업무보랴, 서핑하랴 집에선 노느라 블로깅 하기가 정말 쉽지가 않으니까요. 각설하고 두번째 글에서 RESTful 서비스는 크게 자원과 행위와 컨텐츠의 타입으로 이루어진다고 언급했습니다. 아울러 REST 서비스를 만들기 위한 절차 등을 간단하게 살펴보았습니다. 무엇보다 가장 중요한 핵심은 REST는 자원 중심의 아키텍처다라는 겁니다. 이 '자원'이라는 것부터 오늘의 글을 시작하도록 하겠습니다.
일단 범위를 좁혀서 이 '자원'을 웹상의 자원이라고 구체화시켜봅시다. 이 자원은 동영상이나 일반 문서 혹은 이미지 등등이 될수있습니다. 이러한 웹상의 자원은 무엇으로 이루어져있을까요? 아래와 같이 크게 4가지로 이루어져있다고 보겠습니다.
그 중에서도 먼저 웹의 자원 중 첫번째 가장 중요한 URI를 살펴보겠습니다.
웹상의 자원을 그 특징별로 분류하고 구분하는 작업이 REST기반의 서비스에서는 꼭 필요합니다. 그래야 웹에 자원들을 빠짐없이 일목요연하게 서비스할 수 있기 때문입니다. 자, 우리가 웹상에 뭔가 서비스하려는 그 자원은 대체 어떠한 특징이 있을것이며 어떤패턴을 보일까요? 자원의 특징별로 한번 구분해보기로 합시다.
집합 자원들은 하나 이상의 멤버들로 이루어진 자원들입니다. 서재를 예로 들어보면 /서재 라고 질의하면 아마도 무수한 책의 리스트가 나오겠죠. 보통 REST에서는 이러한 집합 자원들을 표현할 때 복수형으로 질의하는 경우가 많으므로 /책들 혹은 /books 라고 표현하기도 합니다. 집합 자원들의 멤버들은 저마다 고유의 ID값을 가지게 됩니다. 그런데 이 ID값은 자원 제공자가 생성할 수도 있겠고 아니면 클라이언트가 만들기도 합니다. 전자의 경우를 예로 들면 GET으로 /고객계정 과 같이 질의를 하는 경우일테고 후자의경우는 POST방식으로 /고객계정/새ID 와 같이 고객을 등록하는 경우일 겁니다.
만약 집합 자원들 중에서 하나 이상의 자원들을 가져와야할 때의 규칙도 정의해야만 합니다. 예를 들어 /Account?members=all 은 집합 내의 모든 자원을 가져옵니다. 또한 /Account?members=[1234,1235,1236] 은 ID가 1234,1235,1236인 멤버를 가져옵니다.
이번 글에서는 주로 URI 패턴에 따라 보통 REST 서비스를 웹상에 구현하려면 필요한 몇가지 필수 REST URI 정의들을 소개했습니다.
더 하고 싶은 심도깊은 이야기도 몇몇 있기는 하지만 도저히 당분간은 시간이 나질 않을 듯 하네요. 아마도 6월 중순까지는 이렇게 몇페이지 짜리 글은 아마도 힘들지 않을까 싶어요.
아무튼 지금까지의 내용은 사실 REST서비스 구축을 위한 아주 기본적인 내용들입니다. 보안, 성능을 위한 캐시, 버저닝, 단위테스트, 동시성 제어, 개발 및 운영 플랫폼 등등 생각해봐야 할 것들은 너무나 많지요. 모쪼록 하반기에는 이러한 내용으로도 이블로그에 글을 채울 수 있기를 기대합니다.
웹의 자원은 어떻게 이루어져있나.
일단 범위를 좁혀서 이 '자원'을 웹상의 자원이라고 구체화시켜봅시다. 이 자원은 동영상이나 일반 문서 혹은 이미지 등등이 될수있습니다. 이러한 웹상의 자원은 무엇으로 이루어져있을까요? 아래와 같이 크게 4가지로 이루어져있다고 보겠습니다.
- URI: 예) http://calmglow.egloos.com/4119223
- 액션: 예) GET, PUT, POST, DELETE
- 응답코드: HTTP 403
- 표현 코드: 예) application/xml, text/x-json, application/atom+xml
URI의 패턴들
그 중에서도 먼저 웹의 자원 중 첫번째 가장 중요한 URI를 살펴보겠습니다.
웹상의 자원을 그 특징별로 분류하고 구분하는 작업이 REST기반의 서비스에서는 꼭 필요합니다. 그래야 웹에 자원들을 빠짐없이 일목요연하게 서비스할 수 있기 때문입니다. 자, 우리가 웹상에 뭔가 서비스하려는 그 자원은 대체 어떠한 특징이 있을것이며 어떤패턴을 보일까요? 자원의 특징별로 한번 구분해보기로 합시다.
- 일반 자원들
- 간단한 자원
- 복잡한 자원
- 집합 자원들
- 멤버 자원
- 질의 자원
- 페이징 자원
- 정렬 자원
- 알고리즘 기반 자원
집합 자원들은 하나 이상의 멤버들로 이루어진 자원들입니다. 서재를 예로 들어보면 /서재 라고 질의하면 아마도 무수한 책의 리스트가 나오겠죠. 보통 REST에서는 이러한 집합 자원들을 표현할 때 복수형으로 질의하는 경우가 많으므로 /책들 혹은 /books 라고 표현하기도 합니다. 집합 자원들의 멤버들은 저마다 고유의 ID값을 가지게 됩니다. 그런데 이 ID값은 자원 제공자가 생성할 수도 있겠고 아니면 클라이언트가 만들기도 합니다. 전자의 경우를 예로 들면 GET으로 /고객계정 과 같이 질의를 하는 경우일테고 후자의경우는 POST방식으로 /고객계정/새ID 와 같이 고객을 등록하는 경우일 겁니다.
멤버 자원
REST에서는 이러한 집합 자원들 속의 멤버들에 접근하기 위한 URI 정의가 필요합니다. 즉 집합 자원속의 '멤버 자원'을 접근하는 규칙을 정의해야 합니다. 이를테면 계정 중에서 id가 1234인 것을 접근하고자 할 때 /Account/1234 일 수도 있겠고 /Account?id=1234 일 수도 있겠지요. 또한 어떤 방식은 입력을 위해서, 어떤 방식은 정보를 얻기 위해 별도로 정의되어야 할 수도 있을 것입니다.만약 집합 자원들 중에서 하나 이상의 자원들을 가져와야할 때의 규칙도 정의해야만 합니다. 예를 들어 /Account?members=all 은 집합 내의 모든 자원을 가져옵니다. 또한 /Account?members=[1234,1235,1236] 은 ID가 1234,1235,1236인 멤버를 가져옵니다.
질의 자원
자원을 웹으로 서비스하면서 이제까지의 방법만으로는 불충분한 경우가 많습니다. 결국 제대로 서비스하려면 보다 유연한 질의 기능이 필요합니다. 때문에 '질의 자원'을 정의하게 됩니다. 보통 '질의 자원'을 정의할 때 정의하기 가장 쉬운 방법은 /Account?name="최진호"&age="34" 와 같이 몇 가지 속성값을 통해서 정의하는 방식입니다. 보다 직관적이기는 하지만 유연성이 많이 떨어집니다. 이보다 더 유연하고 고급화된 방법은 필터 개념을 두는 겁니다. 즉 /Account?filter="논리 표현식" 처럼 보다 다양하고 복잡한 질의를 수행할 수 있도록 하는 것이죠. 여기서 '논리표현식'은 보통 이 논리 표현식을 그대로 알아먹을 수 있는 내부 데이타 표현 시스템의 형식을 그대로 따르는 편이 좋습니다. 즉 SQL 언어나 JPA 질의등이 예가 될 수 있습니다. 이 필터를 쓰는 방식의 예를 좀 더 들어보면 /제품?filter=단가 gt2000 : '제품 단가 2000보다 큰 것들', /고객?filter=name in ('김','이','박') : '이름속에 김,이,박이 있는 고객' 등등이 있습니다.페이징 자원
아까 /books 와 같이 서재 안의 모든 책을 가져오는 무식한 질의를 예로 들었지만 현실적으로는 적절치 않은 방식이겠죠. 성능이나 안정성 그리고 사용성을 위해서라도 '페이징 자원'은 꼭 필요합니다. 자원 중에 그 순서가 명확한 경우에는 /Account?members=[0-9] /Account?members=[10-19] 와 같은 방법으로 자원을 가져오는 것이 가능합니다. 하지만 어떤 경우에는 순서는 명확하지만 순서내의 숫자가 불규칙적으로 산재된 경우가 있습니다. 즉 id가 1,3,10,11,12,13,14,15,16,44 와 같은 방식일 수 있겠죠. 이런 경우에는 /Account?start=0&count=10 이나 /Account?start=10&count=10 처럼 특정 position을 정하고 거기에서 부터 멤버 갯수를 셈하여 접근하는 방식도 매우 유용한 방식이죠. 아무튼 이러한 '페이징 자원'방식은 그 자원들이 집합 내에서 특정 순서를 가지고 있는 경우에만 유용한 방식이라 할 수 있겠습니다.정렬 자원
'정렬 자원'은 말 그대로 어떤 기준에 입각하여 정렬하여 자원을 접근하고자 할 때 유용하겠죠. 가장 간단한 방법은/Account?sort=ascending 이나 /Account?sort=descending 처럼 기본 값을(이를테면 id값) 기준으로 정렬하여 볼 수 있습니다. 또한 특정 필드값을 기준으로 정렬하고자 할 때에는 /Account?sortBy="필드1"처럼 정의해두면 다양한 활용이 가능하겠죠.알고리즘 자원
자원 정의의 무한한 가능성을 소개하기 위해 마지막으로 '알고리즘 자원'을 설명드리겠습니다. 이제까지는 자원의 대상은 눈에 보이고 구체적인 대상이었습니다만 때로는 어떤 비즈니스 로직이나 프로세스가 자원의 대상이 될 수도 있습니다. 예를 들어 '이체'라는행위를 자원으로 보면 어떨까요? 자, 이체라는 자원을 /Transfer라고 정의하고 이것을 행위와 관련지어서 자원을 세부정의해 보겠습니다.| 액션 | 집합 | 설명 |
| GET | 이전의 이체의 목록을 반환 | /Transfer/123 : 특정 이체 번호에 해당하는 이체 기록을 전달 |
| POST | 새로운 이체를 수행! | |
| PUT | 미 지원 | 현재 진행 중인 이체 절차를 변경 |
| DELETE | 미 지원 | 이체 취소 |
이번 글에서는 주로 URI 패턴에 따라 보통 REST 서비스를 웹상에 구현하려면 필요한 몇가지 필수 REST URI 정의들을 소개했습니다.
더 하고 싶은 심도깊은 이야기도 몇몇 있기는 하지만 도저히 당분간은 시간이 나질 않을 듯 하네요. 아마도 6월 중순까지는 이렇게 몇페이지 짜리 글은 아마도 힘들지 않을까 싶어요.
아무튼 지금까지의 내용은 사실 REST서비스 구축을 위한 아주 기본적인 내용들입니다. 보안, 성능을 위한 캐시, 버저닝, 단위테스트, 동시성 제어, 개발 및 운영 플랫폼 등등 생각해봐야 할 것들은 너무나 많지요. 모쪼록 하반기에는 이러한 내용으로도 이블로그에 글을 채울 수 있기를 기대합니다.
공유하기 버튼
|
|



덧글
2009/06/10 20:03 # 답글
비공개 덧글입니다.