Internet Computing Laboratory @ KUT Youn-Hee Han Restlet - WebService Internet Computing Laboratory @ KUT Youn-Hee Han
REST 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
웹상의 모든 것들은 URL로 표현 (Representation) 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 REST (XML over HTTP) 85% SOAP 15% 구글이 오랫동안 제공해온 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 응답 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
O X "서버 주소 + 서비스 이름 + 자원" REST방식의 호출 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 Restlet 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
<html> …. </html> 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) WebService 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() { 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 public void handle(Request request, Response response) { String message = "Orders of user \"" Restlet order = new Restlet(getContext()) { String message = "Order \"" + request.getAttributes().get("order") + "\" for user \"" 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