230 likes | 252 Views
Restlet - WebService. Internet Computing Laboratory @ KUT Youn-Hee Han. REST. REST 란 대규모 네트워크 시스템을 위한 아키텍처 2000 년 Roy Fielding 의 박사 학위 논문에서 처음 제안 . Re presentational S tate T ransfer 의 약자 Architectural Styles and the Design of Network-based Software Architectures (DOCTOR OF PHILOSOPHY)
E N D
Restlet - WebService Internet Computing Laboratory @ KUT Youn-Hee Han
REST • REST란 대규모 네트워크 시스템을 위한 아키텍처 • 2000년 Roy Fielding의 박사 학위 논문에서 처음 제안. • Representational State Transfer 의약자 • Architectural Styles and the Design of Network-based Software Architectures(DOCTOR OF PHILOSOPHY) • http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm • REST의 원래 뜻 • 웹과 같은 대규모 네트워크 시스템을 위한 원칙들의 모음 • 최근 추가된 뜻 • XML과 HTTP를 사용하는 단순한 웹 기반 인터페이스를 지칭(즉, REST의 원칙을 따르는 Web Services) WebService
Rest • REST (Representational State Transfer) • SOAP, XML-RPC보다 간단 • OPEN-API 구현에 많이 사용 • Naver의 OPEN API들도 REST 방식이라고 할 수 있다. • 많은 웹2.0 회사들이 Open API의 구현 방법으로 많이 사용. • 구글, 플리커, 아마존 등의 Open API가 REST 방식으로 구현되어 공개 • 서비스의 서버 플랫폼 구축에 있어 필수적인 아키텍쳐 • REST는 실제 표준은 아니지만 HTTP/URL/MIME Type같은 웹 표준만을 사용. • 따라서 실제 표준 기술이기도 하다 WebService
Rest 방식 웹상의 모든 것들은 URL로 표현 (Representation) CLICK URL 다른 URL • 잘 정의된 URL을 통해 웹 애플릿케이션을 구동 • 그 결과(State)를 전달(Transfer)받아 처리 Representational State Transfer은 잘 디자인된 웹 어플리케이션이 어떻게 동작하는 지에 대한 이미지를 떠올리게 하가 위한 용어이다. 웹 페이 지들의 네트워크가 있고 사용자가 링크를 선택하면 다음 페이지가 보여진다. 즉 웹을 Virtual State Machine이라고 생각하면 링크를 선택함으로 써 State가 변하고 Next State Representation(다음 페이지)가 보여지게 된다 WebService
Rest • REST는 웹이 성공을 이룰 수 있었던 것은 다음과 같은 특징을 가졌기 때문이라고 주장 • 상태를 유지하지 않는 (Stateless) 클라이언트/서버 구조를 가진다. • 작고 어디에서나 적용되는 인터페이스를 가진다. • GET, POST, PUT, DELETE • PUT과 Delete 메소드는 HTTP스펙에는 존재하지만 지원하는 브라우저는 많지 않다. • 모든 자원은 URL를 이용하여 유일하게 지칭될 수 있다. • 자원들의 표현(Representation)들이 URL을 통해 서로 연결되어 있다. • REST의 원칙에는 쿠키나 세션을 사용하지 않는다. WebService
Rest vs SOAP • 구글이오랫동안 제공해온 SOAP 기반 검색 API서비스가 2006년 12월 5일 부로 중단 • 대신 구글은 REST 기반의 Ajax Search API를 대안으로 제시 • 2003년도 아마존이 제공한 두 가지 인터페이스의 점유율 REST (XML over HTTP) 85% SOAP 15% WebService
REST방식의 호출 요청 http://wisefree.com/employee 응답 <?xml version="1.0"?><p:Employee xmlns:p="http://wisefree.com" xmlns:xlink="http://www.w3.org/1999/xlink"><Employee id="603045" xlink:href="http://wisefree.com/employee/603045"/><Employee id="741146" xlink:href="http://wisefree.com/employee/741146"/></p:Employee> WebService
REST방식의 호출 요청 http://wisefree.com/employee/603045 응답 <?xml version="1.0"?><p:Employee xmlns:p="http://wisefree.com" xmlns:xlink="http://www.w3.org/1999/xlink"><Employee-ID>741146</Employee-ID><Name>jisu park</Name><Resume xlink:href="http://wisefree.com/employee/741146/resume/"/></p:Employee> WebService
REST방식의 호출 "서버 주소 + 서비스 이름 + 자원" O http://wisefree.com/employee/603045 X http://wisefree.com/employee/getEmployee?id=603045 WebService
REST방식의 호출 URL을 통해 필요한 자원을 계속해서 추적하여 얻어(HTTP GET) 가거나 삽입(HTTP PUT), 삭제(HTTP DELETE)할 수 있게 분류 설계한다. 결코 한번에 모든 정보를 제공해서는 안 된다. http://wisefree.com/employee전체 직원 명단을 얻어 온다.http://wisefree.com/employee/603045특정 직원의 자세한 정보를 얻어 온다.(HTTP GET)http://wisefree.com/employee/603045특정 직원의 해당 정보를 갱신 온다.(HTTP PUT) WebService
Daum 오픈 API의 Rest • 실행결과 • http://dna.daum.net/examples/php/parseSIMPLEXML.php <?php error_reporting(E_ALL);$request = 'http://apis.daum.net/search/blog?apikey=[사용자 인증키]&q='.urlencode('다음');$response = file_get_contents($request);if ($response === false) { die('Request failed');}$phpobject = simplexml_load_string($response);if ($phpobject === false) { die('Parsing failed');}$channel = $phpobject->channel;echo "<h1>".$channel->title."</h1><br />";echo "<h2>검색결과: ".$channel->totalCount."</h2><br />";foreach($channel->item as $value) { echo "제목: ".$value->title."<br />"; echo "내용: ".$value->description."<br />"; echo "<hr />";} ?> WebService
자바에서의 Rest • Java • XML과 웹 서비스 관련 API 투자 • JAX-WS2에서 HTTP바인딩과 함께 REST 지원 • JAX-WS의 핵심은 SOAP-WSDL이여서 그다지 쓰이지 않았음. • Restlet • 자바를 위한 경량화 REST framework • 오픈소스 프로젝트 • 서블릿의 프로그래밍 모델을 기반 • JSR 311 Java API for RESTful Web Services (이하 JSR 311) • Restlet 홈페이지 • http://www.restlet.org/ • 썬에서 RESTful Web Services API와 개발 환경을 배포 • http://developers.sun.com/web/swdp/index.jsp WebService
Servlet & Restlet • Servlet • Restlet • Servlet보다 경량, 세션 및 쿠키 지원이 없다 <html> …. </html> { resultCount :5, results : [ 1,2,3,4,5] } WebService
Restlet Example 1 • HelloWorld 예제 – Server • 컴파일 : compile –d . src\Restlet_helloworld.java • 실행 : run kut.ime.Restlet_helloworld src\Restlet_helloworld.java package kut.ime; import org.restlet.Restlet; import org.restlet.Server; import org.restlet.data.MediaType; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; public class Restlet_helloworld { public static void main(String[] args) throws Exception{ // Creating a minimal Restlet returning "Hello World“ Restlet restlet = new Restlet() { @Override public void handle(Request request, Response response) { response.setEntity("Hello World!", MediaType.TEXT_PLAIN); } }; // Create the HTTP server and listen on port 8182 new Server(Protocol.HTTP, 8182, restlet).start(); } } WebService
Restlet Example 1 • HelloWorld 예제 – Client • 컴파일 : compile –d . src\Client_helloworld.java • 실행 : run kut.ime.Client_helloworld src\Client_helloworld.java package kut.ime; import java.io.IOException; import org.restlet.Client; import org.restlet.data.Method; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.resource.Representation; public class Client_helloworld { public static void main(String[] args) throws IOException{ Request request = new Request(Method.GET, "http://localhost:8182"); Client client = new Client(Protocol.HTTP); Response response = client.handle(request); Representation output = response.getEntity(); output.write(System.out); } } WebService
Restlet Example 2 • 폼 데이터 보내기 예제 – Server • 컴파일 : compile –d . src\Application.java • 실행 : run kut.ime.Application src\Application.java package kut.ime; import org.restlet.Restlet; import org.restlet.Server; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; public class Application{ public static void main(String[] args) throws Exception { Restlet_User user = new Restlet_User(); Server server = new Server(Protocol.HTTP, 8182, user); server.start(); } } class Restlet_User extends Restlet{ @Override public void handle(Request request, Response response) { Form form = new Form(request.getEntity()); String name = form.getFirstValue("name"); String number = form.getFirstValue("number"); response.setEntity("Restlet - \nName : " + name + ", Number : " + number, MediaType.TEXT_PLAIN); } } WebService
Restlet Example 2 • 폼 데이터 보내기 예제 – Client • 컴파일 : compile –d . src\ApplicationTest.java • 실행 : run kut.ime.ApplicationTest src\ApplicationTest.java package kut.ime; import org.restlet.Client; import org.restlet.data.Form; import org.restlet.data.Method; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; public class ApplicationTest { public static void main(String[] args) throws Exception { Request request = new Request(Method.PUT, "http://localhost:8182"); Form form = new Form(); form.add("name", args[0]); form.add("number", args[1]); request.setEntity(form.getWebRepresentation()); Client client = new Client(Protocol.HTTP); Response response = client.handle(request); System.out.println(response.getEntity().getText()); } } WebService
Restlet Example 3 Component 예제 (1/2) src\Component_resource .java package kut.ime; import org.restlet.Component; import org.restlet.Restlet; import org.restlet.data.MediaType; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; public class Component_resource { public static void main(String[] args) throws Exception{ // Create a new Restlet component and add a HTTP server connector to it Component component = new Component(); component.getServers().add(Protocol.HTTP, 8182); // Create a new tracing Restlet Restlet restlet = new Restlet() { @Override public void handle(Request request, Response response) { // Print the requested URI path String message = "Resource URI : " + request.getResourceRef() + '\n' + "Root URI : " + request.getRootRef() + '\n' + "Routed part : " + request.getResourceRef().getBaseRef() + '\n' WebService
Restlet Example 3 • Component 예제 (2/2) • 컴파일 : compile –d . src\Component_resource.java • 실행 : run kut.ime.Component_resource • 테스트 • 웹 브라우저로 “http://localhost:8182/trace/abc/def?param=123” 접속 src\Component_resource .java + "Remaining part: " + request.getResourceRef().getRemainingPart(); response.setEntity(message, MediaType.TEXT_PLAIN); } }; // Then attach it to the local host component.getDefaultHost().attach("/trace", restlet); component.start(); } } WebService
Restlet Example 4 • 파일접속 예제 • 컴파일 : compile –d . src\Component_resource.java • 실행 : run kut.ime.Component_resource • 테스트 : 웹 브라우저로 “http://localhost:8182/” + “d:에 있는 파일명”으로 접속 src\Component_files.java package kut.ime; import org.restlet.Component; import org.restlet.Application; import org.restlet.Directory; import org.restlet.Restlet; import org.restlet.data.Protocol; public class Component_files { public static final String ROOT_URI = "file:\\\\D:\\"; public static void main(String[] args) throws Exception{ Component component = new Component(); component.getServers().add(Protocol.HTTP, 8182); component.getClients().add(Protocol.FILE); Application application = new Application(component.getContext()) { @Override public Restlet createRoot() { return new Directory(getContext(), ROOT_URI); } }; component.getDefaultHost().attach("", application); component.start(); } } WebService
Restlet Example 5 VirtualHost 예제 (1/3) src\Route_example.java package kut.ime; import org.restlet.Component; import org.restlet.Application; import org.restlet.Restlet; import org.restlet.Router; import org.restlet.data.MediaType; import org.restlet.data.Protocol; import org.restlet.data.Request; import org.restlet.data.Response; public class Route_example { public static void main(String[] args) throws Exception{ Component component = new Component(); component.getServers().add(Protocol.HTTP, 8182); component.getClients().add(Protocol.FILE); Application application = new Application(component.getContext()) { @Override public Restlet createRoot() { Router router = new Router(getContext()); Restlet account = new Restlet() { @Override public void handle(Request request, Response response) { WebService
Restlet Example 5 VirtualHost 예제 (2/3) src\Route_example.java String message = "Account of user \"" + request.getAttributes().get("user") + "\""; response.setEntity(message, MediaType.TEXT_PLAIN); } }; Restlet orders = new Restlet(getContext()) { @Override publicvoid handle(Request request, Response response) { String message = "Orders of user \"" + request.getAttributes().get("user") + "\""; response.setEntity(message, MediaType.TEXT_PLAIN); } }; Restlet order = new Restlet(getContext()) { @Override publicvoid handle(Request request, Response response) { String message = "Order \"" + request.getAttributes().get("order") + "\" for user \"" + request.getAttributes().get("user") + "\""; response.setEntity(message, MediaType.TEXT_PLAIN); } }; WebService
Restlet Example 5 • VirtualHost 예제 (3/3) • 컴파일 : compile –d . src\Route_example.java • 실행 : run kut.ime.Route_example • 테스트 – 웹 브라우저로 접속 • http://localhost:8182/users/test • http://localhost:8182/users/test/orders/ • http://localhost:8182/users/test/orders/rest src\Route_example.java router.attach("/users/{user}", account); router.attach("/users/{user}/orders", orders); router.attach("/users/{user}/orders/{order}", order); return router; } }; component.getDefaultHost().attach(application); component.start(); } } WebService