목요일, 7월 18

최근 웹 개발환경 이해 - 진보된 웹 환경 공부 #2 Restlet Framework



개요

지난 글 진보된 웹 환경 공부 #1 에서는 REST라는 설계 철학이 등장한 이유와 함께 그와 같은 설계와 함께 사용해야 하는 URI, JSON 등에 대한 개괄적인 설명을 다뤘습니다. 이번 글에서는 REST를 구현한 RESTful 서비스를 Restlet이라는 Framework를 사용하여 간단히 구현해보겠습니다.

그 전에 REST는 설계에 철학이 담겨있습니다.
제가 철학이라고 말하는 것은, 뭔가 거대 담론을 지칭하는 것은 아니고 단지 "이와 같은 설계를 통해 세상이 이렇게 되었으면 좋겠다." 라는 설계자의 바람이 느껴지는 것을 말합니다.

그렇다면 기존에는 어떤 설계를 사용했는지 그리고 이와 같은 설계의 한계점은 무엇인지 살펴보고 REST를 통해 어떻게 보다 더 좋은 방향으로 프로그래밍을 할 수 있는지 알아보는게 우선이라고 생각해서 이 부분을 추가했습니다.

해서 이 글은 이와 같은 순서로 작성됐으며, 이런 생각을 하시면서 읽으면 되실 것 같습니다.
1. 기존에 범용적으로 사용되던 Web Framework 개괄 설명
2. 1에서 다룬 Framework의 설계
3. 2의 문제점과 한계
4. REST의 개괄 설명은 생략 #1을 참고하세요
5. REST가 지향하는 설계철학
6. Code review
7. 결론 및 내용 요약

[ "기존에 사용되던 Framework의 한계점은 무엇이고 REST는 어떤 장점이 있으며, 어떻게 사용해야 하는가?" ]

Structs Framework

Structs는 2000년도 이전에 크레이그 맥클라나한(Craig McClanahan)에 의해 탄생했으며 MVC 패턴을 구현하기 위해 Java Servlet API를 사용했습니다. Structs외 이 당시 대부분의 Web-Framework는 거의 MVC 패턴을 사용했습니다.

Structs Framework가 사용하는 MVC 패턴의 문제

structs MVC model 2

 Structs에서는 MVC 패턴을 사용하는데 이는 Model-View 간의 결합도를 낮추기 위해서입니다. 객체지향에서 결합도를 낮추는 일은 매우 중요합니다.

 MVC model 2 는 비록 model 과 View 사이에 Bean을 두었지만 단순히 데이터를 주고 받는 매개자 역할을 했기 때문에 Model이나 View의 변화에서 자유롭지 못했습니다.

 그 외에 Server에서 최종적으로 반환하는 것이 View로 UI를 구성하기 위한 부가적인 데이터가 추가되어 있고, 이를 해석하는 과정에 비용이 많이 들었으므로 이 시기에 웹 서비스 간에 유려한 연동은 소원한 일이었습니다.

 만약 상기의 Structs구조에서 Javabean을 View에 binding시키고 View를 보내주는 것이 아닌, 서술가능한 형태의 DataStructure 형태로 Bean을 제공했다면 어땠을까요? 개발자들은 보다 View와 Model간에 연결성이 떨어져 병렬개발(?)이 가능했을 것이고, 외부에서 해당 서비스를 이용하기는 쉬웠을 것입니다. 요것이 현재 REST기반 아키텍쳐의 장점이죠.


Structs Framework의 Http session 문제

 또한 기존 웹 Framework들은 사용자의 로그인 정보등을 유지하기 위해서 세션과 쿠기 등의 부수요소를 사용했는데, 이와 같은 값들은 로그인과 같은 특정 과정을 거친 후에 생성되므로 웹 서비스 간에 연결하고자 할 때에 한 번 이상의 트랜잭션이 추가로 필요로 하게 되었습니다.


Restlet Framework

 다시 말하자면 기존에 사용하던 설계 상의 문제점은, 웹 서비스들 간에 연동도 어렵고, 웹 서비스를 다른 개발자들에게 공개하기도 어려운 상황 속이었습니다. 그러던 중에 REST를 통한 open-api 의 공개와 성공은 많은 개발자들에게 수 많은 웹 서비스들을 API처럼 사용할 수 있는 가능성을 열었고, 결과적으로 개발자와 서비스 모두에게 큰 도움이 되었습니다.


Restlet Framework가 지향하는 설계와 기능


 Restlet Framework는 #1 에서 살펴본 내용처럼 Restlet은 공개한 REST API 들을 URI로 접근할 수 있도록 도와줍니다. 또한 많은 REST API들을 사용할 수 있도록 URI을 각각의 메소드 등에 연결하기 편하게 도와주는 Routing이란 기능을 제공합니다.

 그리고 기존의 설계와는 다르게 Model의 데이터들을 View에 기입한 뒤에 View를 반환하는 것이 필수 구조가 아니고, View와 Model간에 Data를 설명해주는 서술자를 둠으로서 View와 Data간에 결합도는 최소화 할 수 있게 됐습니다.

 이것은 흔히 Front-End, Middle-End, Back-End 라고 부르는 구조처럼, 각 단계마다의 결합도와 의존성을 최소화하고 대신 정해진 규약과 인터페이스에 의한 분업 체계로 바뀌었음을 의미합니다. 이렇게 빠뀐 구조 덕분에 Front-End 에서 python, java, javascript 아무거나 내키는대로 사용할 수 있게 된 것입니다. Front-End Freedom!


Restlet Framework Sample service code review

Restlet Tutorial
Restlet의 기본적인 튜토리얼은 위의 주소를 참고하세요.

Restlet의 1단계는 서버를 만드는 작업입니다.
Restlet에서 서버는 하나의 Component 단위이며,

Component는 VirtualHost-Application의 구조로 이루어집니다.


그러므로 자연스럽게 2단계는 Virtual-Host 설정이고 3단계는 Application 설정입니다. 물론 정해진 순서는 없고 코드를 짜기에 따라서 어플리케이션에서 직접 Component를 올리고 Virtual-Host와 Application을 설정할 수도 있지만, 이번에는, Restlet Framework에 기본적으로 탑재하고 있는 서버 컴포넌트를 올리고 이 위에 어플리케이션을 올리는 작업을 해보도록 하겠습니다.

//HeloWorld
public class HelloWorldRESTMain {
public static void main(String[] args) throws Exception {
   // Create a new Component.
   Component component = new Component();
   // Add a new HTTP server listening on port 8182.
   component.getServers().add(Protocol.HTTP, 8182);
   // Attach the sample application.
    // component.getDefaultHost().attach(new HelloWorldRESTApplication());
   // Start the component.
   component.start();
}
}


컴포넌트를 만들고 8182번 포트를 사용하는 HTTP서버를 올리고, HelloWorldRESTApplication 을 attach 해줍니다.

//HelloWorldRESTApplication
public class HelloWorldRESTApplication extends Application {
    @Override
    public synchronized Restlet createInboundRoot()
    {
        Router router = new Router();
        router.attach("/helloworld",HelloWorldRESTResource.class );
        return router;
    }
}

HelloWorldRESTApplication에서는 helloworld URI에 Resource를 attach하는 역할을 합니다. 여기에 /helloworld 라는 URI는 이제부턴 HelloWorldRESTResource 클래스가 되는 거죠.
Resource는 어떤 역할을 할까요?


Resource는 실질적인 동작을 수행하는 곳 입니다. Router는 URI를 각 Resource로 연결해주는 식별자 역할만을 수행합니다.

REST Framework는 HTTP의 Get, Post, Put, Delete 를 지원하며 Restlet에서는 해당 Resource에 어노테이션을 확인하고 함수를 호출합니다. Get이라면 @Get 어노테이션에 따르는 함수를 호출하죠. 우리는 HelloWorld를 통해 Client에게 JSON을 반환해줄 것입니다.

// HellowWorldRESTResource
public class HelloWorldRESTResource extends ServerResource {
@Get
    public Representation HelloWorld(Representation entity)
    {
JsonRepresentation response = null;
        try
        {
        LinkedHashMap<String, Object> list = new LinkedHashMap<String, Object>();
            list.put("WELCOME_REST", "Hello World");
            response = new JsonRepresentation(list);
         
        } catch(Exception ex)
        {
       
        }
return response;
    }
     
}

JSON을 반환하기 위해 JsonRepresentation 클래스를 사용했습니다.
이제 브라우저로 http://localhost:8182/helloworld 에 접속하게 되면,

{"WELCOME_REST":"Hello World"} 

위와 같은 JSON을 반환받게 됩니다.



마치며

 REST는 매우 강력한 서버 모델이자 동시에 협업 모델이기도 합니다. MVC모델이 그토록 오랜 시간 GUI구현 패턴을 주도해온 이유는 View와 Model의 분리가 디자이너와 개발자에게 좋은 협업 환경을 만들어 주었기 때문입니다.

일보 더 나아가 REST는 개발에 있어 GUI와 서버 구성에 완벽한 독립성을 부여했습니다. GUI 개발자와 서버 개발자는 같은 프로그래밍 언어를 사용할 이유가 전혀 없게 되었다고 봐도 무방합니다. JSON이라는 훌륭한 매개자가 있으니까요. 또한 이를 통해 서비스 간에도 자유로운 협업이 가능해지게 되었습니다. RPC 같은 것과는 비교도 안되죠.

 다음 3부에서는 JSON을 통한 GUI 구성에 있어 MVVM모델을 사용하고 있는 knockout.js라이브러리를 통해 개발자와 퍼블리셔라고 불리는 Html 코더 간에 독립성을 확보하는 예제를 작업해 볼 것입니다.



댓글 없음:

댓글 쓰기