IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  자바 | SOA와 웹서비스 | 오픈 소스  >

RESTful한 웹 서비스 만들기

REST와 RESTlet 프레임워크에 대한 소개

developerWorks
Go to the previous page15 페이지 중 5 페이지Go to the next page

문서 옵션

샘플 코드


제안 및 의견
피드백

튜토리얼 평가

이 컨텐츠를 개선하기 위한 도움을 주십시오.


Restlets

경기와 주자에 대한 CRUD가 상당히 잘 매핑되는 RESTful한 API를 정의해봤다. 그리고 XML 문서로 상호 통신하는 형식을 정의했다. 이 절에서는 서블릿(servlet)을 모델로 한 혁신적인 프레임워크를 사용하여 이 모든 것들을 한데 합쳐보자.

Restlet 프레임워크

Restlet 애플리케이션은 하나의 컨테이너에 존재하는 서블릿 애플리케이션과 닮았다. 하지만 실질적으로는 본다면 두 가지 주요한 방향에서 상당히 다르다. 첫째, Restlet은 HTTP 혹은 HTTP가 이야기하는 쿠키, 세션과 같은 실질적인 상태와 관련한 것에 대해 직접적인 개념을 갖고 있지 않다. 둘째, Restlet 프레임워크는 초경량화되어 있다. 알게 되겠지만 완벽한 기능을 갖춘 RESTful한 애플리케이션은 핵심 Restlet 기본 클래스 몇 개에서 확장(extends)한 소수의 클래스들만으로도 만들 수 있다. 설정과 배치는 기존 컨테이너 모델을 이용할 수 있기 때문에 간단히 web.xml 파일 정도만 고쳐 표준 웹 아카이브(WAR) 파일을 배치한다.

대부분의 경우 Restlet 프레임워크를 이용해 만들어진 수많은 RESTful한 애플리케이션들은 ApplicationResource라는 두 가지 기본 클래스를 필요로 한다. 논리적으로 말해 Application 인스턴스는 URI를 Resource 인스턴스에 매핑한다. Resource 인스턴스는 기본적인 CRUD 명령, 그러니까 GET, POST, PUT, DELETE에 매핑된 CRUD 명령을 다루는 작업을 한다.




위로


경기 애플리케이션

Restlet 프레임워크의 Application 클래스로부터 확장하는 것으로 Restlet 프레임워크를 써보기로 하자. 이 클래스에서 URI에 응답하는 Resource를 정의한다. 이 정의 과정은 프레임워크의 Router 클래스를 써서 행한다. 예를 들어 order/order_id 같은 URI를 갖고 있다면 어떤 객체가 이 요청을 다룰 수 있는지 명시할 필요가 있다. 이 객체는 프레임워크의 Resource 타입 인스턴스다. Listing 5처럼 Router 인스턴스에 붙여(attach) 객체와 URI를 연결한다.


Listing 5. Router 인스턴스를 생성하고 URI를 매핑
                    
Router router = new Router(this.getContext());
router.attach("order/{order_id}", Order.class);

따라서 이 예제에서 URI order/order_id는 논리적으로 Order 클래스에 매핑된다(다음에는 Resource를 확장해 보자).

Aceme Racing은 이미 정의했던 대로 경기와 주자의 다양한 측면에 대해 작업하는 네 가지 패턴에 따라 네 가지의 논리적인 RESTful한 URI를 갖고 있다.

  • /race
  • /race/race_id
  • /race/race_id/runner
  • /race/race_id/runner/runner_id

각 URI의 행동(POST, DELETE, GET 등을 갖고 일어난다고 할 때)은 이 시점에서는 중요치 않다. 각 Resource의 행동은 Resource 인스턴스의 작업이다. 그렇지만 Application 인스턴스는 Router 인스턴스를 통해 이 URI를 (아직 정의되지 않은) Resource에 매핑하는 데 사용된다. Listing6에 보였다.


Listing 6. Resource에 대한 Acme Racing의 URI들
                    
public class RaceApplication extends Application{
 public RaceApplication(Context context) {
  super(context);
 }

 public Restlet createRoot() {
  Router router = new Router(this.getContext());
  router.attach("/race", RacesResource.class);
  router.attach("/race/{race_id}", RaceResource.class);
  router.attach("/race/{race_id}/runner", RaceRunnersResource.class);
  router.attach("/race/{race_id}/runner/{runner_id}", RaceRunnerResource.class);
  return router;
 }
}

기본 클래스인 Application은 추상(abstract) 클래스다. 클래스를 확장하려면 createRoot() 메서드를 구현해야 한다. 이 메서드에서 Router 인스턴스를 생성할 수 있고 Listing 6에서 했던 대로 Resource에 URI를 붙일 수 있다.

알 수 있겠지만 서로 다른 네 개의 Resource 클래스가 있다. 필자는 원하는 방향의 고수준 행동에 맞게끔 URI에 이름을 붙였다. 예를 들어 /race URI는 여러 경기 인스턴스에 대한 작업을 위한 것이다. 결과적으로 Resource 타입은 RacesResource라고 붙였다. id가 URI에 포함되면(/race/race_id처럼) 단일 경기가 처리되고 있음을 내포하고 있다. 따라서 Resource 타입은 RaceResource라고 이름을 붙여 적용했다.




위로


경기 자원

지금까지 서로 다른 네 개의 URI 패턴을 조작하기 위한 Application 인스턴스를 정의했으며 이제 Resource 네 개를 구현해야 한다.

Restlet 프레임워크에서 Resource 타입은 Restlet이라고 알려져 있다. Restlet 프레임워크를 이용해 개발된 RESTful한 애플리케이션들이라면 어떤 것이든 가장 중요한 핵심이다. Application 타입과는 달리 기본 Resource 클래스는 추상형이 아니다. 필요하다면 오버라이드(override)할 수 있는 기본 행동을 갖는 템플릿(templete)에 가깝다.

높은 수준에서 보면 Resource는 오버라이딩을 필요로 하는 네 가지 메서드를 갖는다. 놀라울 것도 없지만, REST의 기준인 기본 HTTP 명령들, 즉 GET, POST, PUT, DELETE에 매핑된다. Resource 클래스는 비추상 클래스이기 때문에 프레임워크에서는 원하는 행동이 불려지도록 하기 위해 메서드가 쌍으로 구현될 필요가 있다. 예를 들어 특정 자원이 DELETE 요청에 응답하도록 하고 싶다면 우선 delete() 메서드를 구현하고 allowDelete() 메서드를 구현하여 이 메서드가 true를 반환하도록 해야 한다(기본값은 false). 기본적으로 대응되는 PUT, POST, DELETE는 메서드가 거짓을 반환하도록 하며, allowGet() 메서드는 true를 반환한다. 이는 읽기 전용 Resource에 대해 메서드 하나만 오버라이드할 필요가 있음을 의미한다(다른 세 가지 경우 중 두 가지 대신). 대신 Resource 클래스에서 setModifcation(true)를 호출할 수 있으므로 개별적으로 HTTP 동사 허용 메서드를 오버라이드할 필요가 없다.

예를 들어 RacesResource는 시스템에서 경기를 서술하는 XML 문서를 이용하여 GET 요청에 응답한다. 사용자는 이 Resource 타입을 통해 새로운 경기를 생성할 수도 있다. 그러므로 RacesResource 클래스는 Resource 기본 클래스로부터 적어도 세 개의 메서드를 오버라이드한다.

  • getRepresentation()
  • allowPost()
  • post()

기억해두자. 기본적으로 Resource 인스턴스는 읽기 전용이다. 그러므로 allowGet() 메서드는 오버라이드될 필요가 없다.




위로



Go to the previous page15 페이지 중 5 페이지Go to the next page
    IBM 소개 개인정보 보호정책 문의