메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

REST와 Flex

한빛미디어

|

2010-02-24

|

by HANBIT

17,040

제공 : 한빛 네트워크
저자 : Luca Mezzalira
역자 : 문성원
원문 : REST and Flex

REST와 Flex에 관한 튜토리얼을 시작하기에 앞서, REST란 무엇이며 왜 사용해야하는지 알아보자.

REST는 REpresentational State Transfer의 줄임말로 XML을 통해 데이터베이스와 통신하는 서비스를 제공하기 쉽게 만든다. 뿐만 아니라 REST는 거대한 웹 어플리케이션을 작은 RIA들로 구성된, 보다 커뮤니케이션이 용이한 시스템으로 변화시킨다.

또 다른 REST의 장점은 클라이언트단과 서버단을 기능적으로 분리하여 각각 다른 방식으로 구현할 수 있게 하는 점이다. 이것은 Ajax나 Flex와 같은 각기 다른 방식으로 구현된 클라이언트에 대해 같은 서비스를 재사용하여 데이터베이스와 통신하는 경우 유용하다. REST는 HTTP 헤더에 기반하며, 클라이언트에서 서버로 전달되는 모든 메시지는 POST, GET, PUT, DELETE와 같은 HTTP 헤더를 통해 전달된다.

이 점은 레코드에 대한 쓰기,읽기,수정,삭제를 정해진 경로에 대해서 정확한 헤더를 사용는 것만으로 가능케 한다는 측면에서 매우 중요하다. 또한 REST는 RIA나 웹사이트와의 안전한 통신을 위해서 다른 웹사이트나 어플리케이션이 서비스에 접근하는 것을 제한하는 토큰인증을 사용한다.

Flex 개발자들이 알고 있는 것처럼 Flex는 HTTP 헤더 중 PUT, DELETE를 지원하지 않는다. 그래서 소켓을 직접 이용해서 이 문제를 해결한 공개 라이브러리인 as3httpclientlib를 사용할 것이다.

시작하기에 앞서

튜토리얼을 시작하기 앞서 Rails와 Flex4를 다운로드 받아 설치해야한다. 만약 이미 설치되어있다면 이 부분은 넘기고 진행하기 바란다.

만약 Mac OS X를 사용한다면 Ruby가 설치되어있을 것이다. 만약 Windows를 사용한다면 http://rubyforge.org/frs/?group_id=167에서 Ruby를 다운로드 받아 설치한다.

Ruby가 이미 설치되어있는지 확인하려면 커맨드창에 ruby -v를 입력한다. 만약 커맨드를 찾을 수 없다면 설치되지 않은 것이므로 다운로드받아 설치한다.

Ruby가 설치되어있다면 Ruby 모듈들을 쉽고 빠르게 다운로드 받을 수 있는 Rubygems를 설치할 수 있다. Rubygems를 설치한뒤 다음 코드를 터미널(Mac OS X)이나 커맨드창(Windows)에 입력하여 Rails, Mongrel 그리고 SQLite를 다운로드 받는다.

RAILS:
sudo gem install rails 
Mongrel:
gem install mongrel 
SQLite:
gem install sqlite3-ruby 
이제 다운로드 한 것들을 검토해보도록 하자.

데이터베이스와 REST간의 상호작용을 만들어내기위해 서버측에 사용할 기술은 Rails를 선택했다. 클라이언트에게 REST 서비스를 제공하기 위한 모든 메소드를 Rails를 이용해 작성할 것이다. Rails는 매우 배우기 쉬운 OOP 언어로 Actionscript3을 배울때도 같은 개념을 이용할 수 있다.

Mongrel은 Rails 어플리케이션을 실행시킬 수 있는 HTTP 서버이다. Mongrel에 대한 자세한 것은 공식 웹사이트를 참조하라.

마 지막으로 SQLite는 Adobe AIR에도 내장되어있는 매우 빠른 자유 데이터베이스이다. SQLite의 특징은 다른 컴퓨터나 모바일 장치로 데이터를 옮길때 단 한개의 파일만 드래그해서 놓으면 된다는 점이다. 게다가 "lite"한 이름과는 다르게 4GB까지의 데이터를 저장할 수 있다. SQLite의 한계에 대해서 더 많은 정보를 원한다면 sqlite.org를 참조하라. 이곳에서 SQLite Database Browser를 다운로드해서 튜토리얼에서 사용할 것을 권장한다. SQLite Database Browser는 매우 사용하기 편리한 무료 어플리케이션이다.

이제 Ruby IDE를 고르는 일이 남았다. Aptana는 단독으로 설치하거나 이클립스 플러그인으로 설치할 수 있다. TextMate(Mac OS X)나 Ruby in Steel for Visual Studio(Windows, 오픈 소스가 아니다)도 선택지가 될 수 있다.

클라이언트단 작업을 위해서는 Flash Builder BETA(스탠드얼론이나 이클립스 플러그인)을 다운로드한다. Flash Builder는 labs.adobe.com에서 찾을 수 있다. 그 다음 REST를 처리하기 위해 ashttpclientlib과 의존관계에 있는 as3crypto 라이브러리를 다운로드 받는다.

download as3crypto
download as3corelib

As3crypto 는 문자열을 암,복호화하는 훌륭한 라이브러리로 주로 Flash나 Flex로 구성된 로그인 폼을 서버로 암호화해서 전송하는데 사용한다. as3corelib도 주로 사용되는 AS3 라이브러리중 하나로 JSON 직렬화 API, 이미지 인코더, 문자열과 숫자 유틸리티등을 포함하고 있다. DELETE와 PUT헤더에 관련된 Flex문제를 해결하기 위한 ashttpclientlib에선 이 두가지 라이브러리를 모두 사용한다.

파일들을 모두 다운로드 받았다면 준비가 끝난 것이다. 이 튜토리얼을 진행하면서 REST와 Flex를 이용해 주소록을 작성하게 될 것이다.

RAILS PART

Rails를 처음 접했을때 나는 매우 쉬우면서도 강력한 언어에 깊은 감명을 받았다. 우선 REST 서비스를 제공하기 위해서 데이터베이스와 관련된 메소드를 작성해야한다. 터미널이나 커맨드창을 열고 프로젝트 폴더를 만든 뒤 이동하여 다음 명령어를 입력한다.
rails rails

cd rails

rake db:create:all

./script/generate scaffold AddressBook firstname:String surname:String role:String description:Text company:String

rake db:migrate 
몇 줄 안되는 코드들만으로 Flex와 연동하기 위한 모든 것이 만들어진다. 멋지지 않은가?

이제 개발 도중에 발생할 수 있는 몇가지 문제를 해결하기 위해서 Rails 코드를 몇가지 수정해야한다. 하지만 그전에 방금 입력한 5줄의 코드를 살펴보도록 하자.

첫번째 줄의 명령어는 Rails 어플리케이션의 뼈대(Skeleton)를 작성한다. 결과물은 rails 파일들을 설치한 폴더에서 찾아볼 수 있다

그림1

두번째 줄을 입력하면 해당 폴더로 이동하게 되며, 세번째 줄은 개발, 배포, 테스트용의 데이터베이스를 만듬으로써 데이터베이스 환경을 구축한다.

Rake는 사용자들이 사용하는 명령을 자동화한 라이브러리를 포함하는 Ruby용 유틸리티이다. 보다 많은 정보는 http://rake.rubyforge.org/에서 확인할 수 있다.

Rake로 데이터베이스를 작성하는 경우 앞서 언급한 SQLite Database browser를 사용해서 비쥬얼 모드로 작성하고 싶다면 sourceforge에서 다운로드 받을 수 있다.

데 이터베이스에게 REST한 접근을 위한 MVC 아키텍쳐의 발판 코드(scoffold)를 만드는 일을 스캐폴딩(scaffolding)이라고 한다. 스캐폴딩은 특정 프레임워크에서 동작하는 데이터베이스 기반 어플리케이션을 만드는 방법이다. 지금 데이터베이스와 통신하기 위한 발판 코드는 Ruby를 사용하여 만들어지게 된다.

마지막 줄의 코드는 모델을 SQLite 개발 데이터베이스 환경으로 마이그레이션한다. 만약 Rails가 어떻게 동작하는지 궁금하다면 rails>db>migrate에 있는 임시파일을 참조하도록 하자.

이제 설정을 테스트하기 위해 터미널(혹은 커맨드창)에 다음 명령어를 입력한다.
./script/server 
엔터키를 입력하면 Mongrel이 기동하는데 웹브라우져를 열고 http://localhost:3000/으로 접속하면 확인할 수 있다. 정상적으로 시작되었다면 다음과 같이 표시될 것이다.

그림2

만약 Mongrel이 동작한다면 Rails의 코드를 수정해보도록 하자.

우선 rails>app>controllers 폴더안의 open_address_books_controller.rb 파일을 열어, 데이터베이스의 모든 데이터를 리턴하게끔 create 함수를 수정한다.
def create 
    @address_book = AddressBook.new(params[:address_book])
    respond_to do |format|
        if @address_book.save
            flash[:notice] = "AddressBook was successfully created."
            @finalData = AddressBook.all
            format.xml { render :xml => @finalData.to_xml(:dasherize => false }
        else format.xml { render :xml => @address_book.errors, :status => :unprocessable_entity }
        end
    end
end 
마지막으로 모든 to_xml 메소드를 이 코드와 같이 수정한다.

format.xml { render :xml => @address_books.to_xml(:dasherize => false ) }

이 설정은 Flex나 Flash와 연동할때 중요하다. Flex나 Flash는 XML Node에 dash가 입력되는 것을 허용되지않기 때문에 이 설정을 통해 모든 dash를 underscore로 변환시켜야한다.

같은 폴더의 application_controller.rb를 열어 protect_from_forgery의 주석을 해제하고 self.allow_forgery_protection=false를 추가하는 것으로 Rails 코드의 수정은 끝난다.

이 변경은 로컬 테스트용임을 명심하라. 이 라인은 Cross-Site Request Forgery attack을 방지하기 위한 부분이며 이것을 변경하는 것은 외부 서버에서의 REST 요청 데이터를 토큰없이 모두 허용하겠다는 의미이다.

FLEX PART

Flex 파트는 직접 GUI를 작성한 GUI나 코드 베이스로써 Flash Catalyst를 사용해 만들어진 .fxp파일을 사용 할 수 있다. .fxp파일은 이곳에서 얻을 수 있다.

주소록의 인터페이스는 모든 사람의 성과 이름, 회사가 표시되는 커스텀 아이템 렌더러를 가진 리스트 형태이다. 또 오른쪽에는 SQLite 데이터베이스에 저장된 상세 정보가 표시되는 흰색 상자도 확인할 수 있다.

그림3

Flash Catalyst파일을 가지고 먼저 해야할 일은 새로운 커스텀 컴포넌트를 추가하는 것이다.(MainView.mxml이라고 부르자) 그 다음 기본 어플리케이션의 모든 MXML파일을 열어 다음과 같이 수정한다.

    
    
    
    
    
        
    
    
        
        
            
            
            
            
        
        
            
            
        
        
        
    
    
    
 
원본 Catalyst 파일에 "Create New"를 추가하고 "Delete"와 "Save"버튼을 수정했다. 또한 인터페이스에 Spark 테마를 적용하기 위해 프로젝트 설정을 변경하는데, 이 설정은 Catlyst에서 만들어진 프로젝트에만 유효하며, Flash Builder의 Catalyst를 통해 작성된 프로젝트에선 수정할 수 없다.

MXML안의 GUI 정의를 마치고나서 Flex4 프레임워크에서 제공하는 Group클래스를 확장하여 MXML의 노드인 MainGroupView를 작성한다. 이 클래스에 정의되야할 것들은
  • 데이터베이스로부터 모든 데이터를 가져오는 메소드
  • 데이터베이스에서 특정 인물을 삭제하는 메소드
  • 특정 인물의 정보를 수정하는 메소드
  • 데이터페이스에 새 인물을 추가하는 메소드
메소드를 작성하기 전에 REST가 어떻게 동작하는지 다시 확인해보자. 다음 테이블은 어떻게 REST가 동작하는지를 나타낸다.
  • 모든 데이터를 가져옴 → http://localhost:3000/address_books.xml (HTTP 헤더: GET)
  • 특정 레코드를 가져옴→ http://localhost:3000/address_books/1.xml (HTTP 헤더: GET)
  • 특정 레코드를 수정 → http://localhost:3000/address_books/1.xml (HTTP 헤더: PUT과 새로 데이터베이스에 저장할 데이터의 바이트 배열)
  • 특정 레코드를 삭제→ http://localhost:3000/address_books/1.xml (HTTP 헤더: DELETE)
  • 새 레코드를 추가→ http://localhost:3000/address_books.xml (HTTP 헤더: POST와 데이터베이스에 추가할 데이터의 XML)
이 예제에서는 이 메소드들의 구현을 위해 HTTPService 클래스와 as3httpclientlib 라이브러리를 사옹한다. 앞서 언급했듯이 HTTPService 클래스만으론 PUT과 DELETE 헤더를 사용할 수 없으므로 as3httpclientlib 라이브러리를 사용하도록 한다.

어플리케이션이 시작할때 데이터베이스에 저장된 데이터로 리스트 컴포넌트를 채울 수 있다.(SQLite Database Browser나 Rails 콘솔[터미널이나 프롬프트에서 ./script/console로 실행]을 사용할 수 있다.) 이 샘플은 HTTPService를 사용해 모든 데이터를 요청한다.
public function init():void{
    service = new HTTPService();
    service.addEventListener(ResultEvent.RESULT, restResult);
    service.addEventListener(FaultEvent.FAULT, restFault);
    service.resultFormat = "e4x";
    service.method = "POST";
    callRestService("address_books.xml", ALL_DATA);
}

private function callRestService(_request:String, _service:String, _data:XML = null):void{
    serviceState = _service;
    service.url = SERVER_URL + _request;
    if(isNewPerson){
        service.contentType = "application/xml";
    }
    service.send(_data);
} 
callRestService()는 HTTPService를 이용해서 데이터를 요청하는 함수로 같은 HTTPService 변수를 경로만 변경하여 모든 레코드를 가져오거나 한개를 가져오는 데에 사용한다.

그 다음 as3httpclientlib를 사용하여 추가와 수정 메소드를 작성한다.
public function saveData():void{
    if(isNewPerson){
        callRestService("address_books.xml", NEW_PERSON, createXMLContent());
    } else {
        var client:HttpClient = new HttpClient();
        var uri:URI = new URI(SERVER_URL + "address_books/" + currentPerson +".xml?_method=put");
        client.addEventListener(HttpRequestEvent.COMPLETE, refresh);
        var ba:ByteArray = new ByteArray();
        ba.writeUTFBytes(createXMLContent());
        ba.position = 0;
        client.put(uri,ba,"application/xml");
    }
}

private function createXMLContent():XML{
    var tmpXml:XML = new XML();
    tmpXml.appendChild();
    tmpXml.appendChild();
    tmpXml.appendChild();
    tmpXml.appendChild();
    tmpXml.appendChild();
    var nameArr:Array = String(nameField.text).split("");
    tmpXml.company = companyField.text;
    tmpXml.description = descr.text;
    tmpXml.firstname = nameArr[0];
    tmpXml.role = roleField.text;
    tmpXml.surname = nameArr[1];
    return tmpXml;
} 
httpclient 변수를 사용할때에는 반드시 URL을 정의하고 REST 서비스를 사용하여 전송할 데이터의 바이트배열을 만들어야하는데, createXMLContent() 함수는 Flex 폼 양식에 입력된 모든 데이터로부터 레코드의 추가나 수정시에 사용할 XML을 만들어낸다. 또한 HttpClient 변수는 URLRequest가 아닌 as3corelib의 URI 클래스를 사용한다.

마지막으로 추가와 삭제 메소드를 추가하자.
public function deleteData(evt:MouseEvent):void{
    var client:HttpClient = new HttpClient();
    var uri:URI = new URI(SERVER_URL + "address_books/" + currentPerson + ".xml");
    client.addEventListener(HttpRequestEvent.COMPLETE, refresh);
    client.del(uri);
} 
이 함수에서 데이터베이스에 대한 인물의 수정, 삭제를 httpclient 객체의 del 메소드와 put 메소드를 통해 구현한다. 즉 모든 작업은 다음의 프로세스를 따른다.
  • 액션에 맞는 정확한 경로를 정의한다.
  • 데이터를 요청하는 메소드라면 데이터를 전송한다.
  • 서버측의 응답을 수신한다.
이 프로세스는 HTTPService 객체나 HttpClient를 사용할때도 적용된다.

최종 샘플은 여기서 다운로드 할 수 있다.

결론

REST는 서버측과 통신하기 위한 흥미롭고 쉬운 기술이다. 다만 Flex나 Flash의 다음 버젼에선 헤더에 관련된 이슈가 해결되어 as3httoclientlib과 같은 별도의 라이브러리 추가 없이 REST를 구현할 수 있길 바란다.
TAG :
댓글 입력
자료실

최근 본 상품0