Showing posts with label RESTful. Show all posts
Showing posts with label RESTful. Show all posts

Sunday, March 18, 2018

How-to: Building RESTful API on Ruby on Rails

Halo semua, kembali lagi di Blog Nostra!

Kali ini kami akan membagikan tentang bagaimana cara mengimplementasi RESTful API pada Ruby on Rails. Sebelum memulai, kami akab memberikan beberapa informasi mengenai REST API dan Ruby on Rails itu sendiri.

- What is Ruby on Rails?
Ruby on Rails (disingkat menjadi Rails) adalah framework yang ditulis dengan bahasa pemrograman Ruby, yang diperkenalkan pertama kali pada tahun 2004. Rails termasuk server side, yang berarti semua proses dijalankan pada server, bukan pada client's browser. 

- What is RESTful API?
RESTful API adalah application program interface yang menggunakan HTTP request untuk mengolah data. Pertama kali diperkenalkan pada tahun 2000 oleh Roy Fielding. REST API banyak digunakan oleh web service development.

Kenapa sih menggunakan Rails? Dari segi development, less painful, karena hanya dengan sebuah script, bisa me-generate model dan controller nya. Selain itu, Rails juga mudah dibaca, bahkan oleh orang yang tidak memiliki dasar pemrograman.

Nah langkah-langkah untuk menggunakan Rails adalah:
- Install Ruby
brew install ruby
- Install Rails
brew install rails
- Konfigurasi database (jika diperlukan)
- Run Rails
rails s

note: jika ingin menambahkan dependency pada Gemfile, lakukan `bundle install` untuk me-include dependency yang baru anda masukan

Script untuk membuat Model:
`rails g model {nama model} {nama variable}:{tipe data} {nama variable}:{tipe data} ...`

Script untuk membuat Controller:
`rails g controller {nama controller}`

Setelah men-define apa yang akan dilakukan oleh controller, saatnya mendefinisikan route untuk method-method yang ada di controller. berikut salah satu contoh controller dan route nya:



Wala, sudah jadi deh RESTful API menggunakan Rails! Selamat mencoba!
Keep smart, keep code, and make money!

Friday, September 18, 2015

RESTFul web service dengan RESTEasy

Apa yang dibutuhkan untuk membuat API web service berbasis Restful?
Jika kita menggunakan java banyak sekali framework yang bisa digunakan untuk membuat Restful dari web application. Contohnya : Apache CFX, JAX-RS, Jersey, Spring MVC.
Yang paling populer menurut saya adalah Spring MVC. Karena  Spring Framework sudah cukup lengkap. Sudah menyediakan banyak fitur, seperti dependency injection, ORM support, MVC dan lain lain.
Tapi kalau kita hanya ingin membuat webservice API yang skalanya kecil. Menurut saya agak cukup rumit karena library dependency yang cukup banyak apalagi harus configurasi juga di ApplicationContext xml.
Ada sebuah library java yang biasa digunakan untuk membangun web application yang bisa mengekspose RestFull webservice API.
Kita akan mencoba Menggunakan RESTEasy. Library ini termasuk dalam JBoss project. Aplikasi kita tidak harus dijalankan diatas JBoss App server, bisa dijalankan di app server yang lain seperti (tomcat, jetty, dan lainnya). Sudah memenuhi standart spesifikasi JAX-RS.
Dokumentasinya ada di sini : https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/index.html
Intinya JAX-RS membantu kita untuk melakukan mapping java class (POJO) menjadi web resource
JAX-RS memiliki beberapa standar annotasi seperti berikut ini :
  • @Path specifies the relative path for a resource class or method.
  • @GET, @PUT, @POST, @DELETE and @HEAD specify the HTTP request type of a resource.
  • @Produces specifies the response Internet media type
  • @Consumes specifies the accepted request Internet media types.
Secara garis besar kita hanya membuat class java yang diberikan anotasi jax-rs dan didaftarkan di web.xml

Tambahkan maven dependency
 <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-jaxrs</artifactId>  
       <version>3.0.4.Final</version>  
     </dependency>  
     <dependency>  
       <groupId>org.jboss.resteasy</groupId>  
       <artifactId>resteasy-jackson-provider</artifactId>  
       <version>3.0.4.Final</version>  
     </dependency>  

Sebagai contoh buat class pojo yang akan kita ekspos sebagai JSON di api kita
 public class Employee extends Base {  
   private String name;  
   private String email;  
   private String phone;  
   private String address;  
   public Employee() { }  
   public Employee(Integer id, String name, String email, String phone, String address) {  
     this.id = id;  
     this.name = name;  
     this.email = email;  
     this.phone = phone;  
     this.address = address;  
   }  
   public String getName() {  
     return name;  
   }  
   public void setName(String name) {  
     this.name = name;  
   }  
   public String getEmail() {  
     return email;  
   }  
   public void setEmail(String email) {  
     this.email = email;  
   }  
   public String getPhone() {  
     return phone;  
   }  
   public void setPhone(String phone) {  
     this.phone = phone;  
   }  
   public String getAddress() {  
     return address;  
   }  
   public void setAddress(String address) {  
     this.address = address;  
   }  
 }  

Buat class service employee yang bertugas untuk mengekpose endpoint yang kita perlukan. Misalnya kita akan membuat fungsi add, find, delete employee.
 import javax.ws.rs.*;  
 import javax.ws.rs.core.Response;  
 import java.util.ArrayList;  
 import java.util.List;  
 import java.util.logging.Logger;  
 @Path("/person")  
 public class EmployeeService {  
   private static final Logger LOGGER = Logger.getLogger(EmployeeService.class.getSimpleName());  
   private List<Employee> listEmployee = new ArrayList<Employee>();  
   public EmployeeService(){  
     listEmployee.add(new Employee(1, "budi", "budi@gmail.com", "081901444", "jakarta"));  
   }  
   @Path("/")  
   @Consumes("application/json")  
   @Produces("application/json")  
   @PUT  
   public Response addEmployee(Employee employee){  
     listEmployee.add(employee);  
     return Response.status(200).entity("new employee id "+employee.getId()).build();  
   }  
   @Path("/")  
   @Produces("application/json")  
   @GET  
   public Response findAllEmployee(){  
     return Response.status(200).entity(listEmployee).build();  
   }  
   @Path("/{id}")  
   @Produces("application/json")  
   @GET  
   public Response findById(@PathParam("id") Integer id){  
     Employee employee = listEmployee.get(id);  
     if(employee != null) return Response.status(200).entity(employee).build();  
     return Response.status(Response.Status.NOT_FOUND).build();  
   }  
   @Path("/{id}")  
   @Produces("application/json")  
   @DELETE  
   public Response DeleteById(@PathParam("id") int id){  
     Employee result = listEmployee.remove(id);  
     if(result != null) return Response.status(200).build();  
     return Response.status(Response.Status.NOT_FOUND).build();  
   }  
 }  

Register class service employes tadi ke dalam class jax-rs application (misalnya kita beri nama RestApplication).
 import javax.ws.rs.core.Application;  
 import java.util.HashSet;  
 import java.util.Set;  
 
 public class RestApplication extends Application {  
   private Set<Object> singletons = new HashSet<Object>();  
   public RestApplication() {  
     singletons.add(new EmployeeService());  
   }  
   @Override  
   public Set<Object> getSingletons() {  
     return singletons;  
   }  
 }  

Daftar class application tadi ke web.xml
 <?xml version="1.0" encoding="UTF-8"?>  
 <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
   <!-- restEasy servlet config -->  
   <servlet-mapping>  
     <servlet-name>resteasy-servlet</servlet-name>  
     <url-pattern>/rest/*</url-pattern>  
   </servlet-mapping>  
   <!-- this should be the same URL pattern as the servlet-mapping property -->  
   <context-param>  
     <param-name>resteasy.servlet.mapping.prefix</param-name>  
     <param-value>/rest</param-value>  
   </context-param>  
   <servlet>  
     <servlet-name>resteasy-servlet</servlet-name>  
     <servlet-class>  
       org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher  
     </servlet-class>  
     <init-param>  
       <param-name>javax.ws.rs.Application</param-name>  
       <param-value>com.nostratech.gcm.notification.rest.RestApplication</param-value>  
     </init-param>  
   </servlet>  
   <session-config>  
     <session-timeout>  
       30  
     </session-timeout>  
   </session-config>  
 </web-app>  

Kita run web application kita (bisa dideploy diatas application server).

- GET /person/0
 {  
   "id": 1,  
   "version": null,  
   "name": "budi",  
   "email": "budi@gmail.com",  
   "phone": "081901444",  
   "address": "jakarta"  
 }  

- PUT /person/  (application/json)
 {  
   "id": 2,  
   "name": "andri",  
   "email": "andri@gmail.com",  
   "phone": "08190166",  
   "address": "bandung"  
 }  

- GET /person/

Referensi :
http://resteasy.jboss.org/ dan http://resteasy.jboss.org/docs
jax-rs spesifications : https://jax-rs-spec.java.net/nonav/2.0-rev-a/apidocs/index.html
source code (web app project yang menggunakan RestEasy) : https://bitbucket.org/andri_khrisharyadi/sample-gcm-sever

Terima kasih dan selamat belajar dan mencoba :)






Sunday, December 14, 2014

Spring MVC : Rest Controller Versioning menggunakan Custom Annotation

Bagi kita yang tidak asing dengan Spring framewok tentu sangat mudah untuk membuat Rest Api dengan menggunakan class Controller. Kita hanya tinggal membuat method yang akan diexpose sebagai rest api dengan menggunakan RequestMapping.
Nah bagaimana jika kita ingin menggunakan versioning pada Rest APInya. Misalnya ada kasus seperti  ini :
Kita sudah punya Rest Api : /person. Tetapi pada suatu saat ada pengembangan baru di Api tersebut dan Api yang lama tidak boleh dihilangkan dulu karena masih ada pihak yang menggunakannya. Maka kita perlu memberikan version pada Rest api tersebut. Rest api yg lama akan dibiarkan. Kemudian dibuat rest api yang baru dengan nama /v2/person.
Cara yang paling sederhana yakni kita buat method controller baru dan diberi RequestMapping("/v2/person").
Tapi cara ini sebenarnya membuat code menjadi tidak clean dan tidak konsisten dalam penamaan.

Pada tulisan saya berikut ini akan saja coba cara untuk melakukan versioning menggunakan @Annotation dan custom RequestMapping.

1. Kita buat dulu class ApiVersion annotation

 @Target({ElementType.METHOD, ElementType.TYPE})  
 @Retention(RetentionPolicy.RUNTIME)  
 public @interface ApiVersion {  
   int[] value();  
 }  

2. Buat class custom RequestMapping handler

 public class ApiVersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {  
   private final String prefix;  
   public ApiVersionRequestMappingHandlerMapping(String prefix) {  
     this.prefix = prefix;  
   }  
   @Override  
   protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {  
     RequestMappingInfo info = super.getMappingForMethod(method, handlerType);  
     ApiVersion methodAnnotation = AnnotationUtils.findAnnotation(method, ApiVersion.class);  
     if(methodAnnotation != null) {  
       RequestCondition<?> methodCondition = getCustomMethodCondition(method);  
       // Concatenate our ApiVersion with the usual request mapping  
       if(info != null)  
         info = createApiVersionInfo(methodAnnotation, methodCondition).combine(info);  
     } else {  
       ApiVersion typeAnnotation = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);  
       if(typeAnnotation != null) {  
         RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType);  
         // Concatenate our ApiVersion with the usual request mapping  
         if(info != null)  
           info = createApiVersionInfo(typeAnnotation, typeCondition).combine(info);  
       }  
     }  
     return info;  
   }  
   private RequestMappingInfo createApiVersionInfo(ApiVersion annotation, RequestCondition<?> customCondition) {  
     int[] values = annotation.value();  
     String[] patterns = new String[values.length];  
     for(int i=0; i<values.length; i++) {  
       // Build the URL prefix  
       patterns[i] = prefix+values[i];  
     }  
     return new RequestMappingInfo(  
         new PatternsRequestCondition(patterns, getUrlPathHelper(), getPathMatcher(), useSuffixPatternMatch(), useTrailingSlashMatch(), getFileExtensions()),  
         new RequestMethodsRequestCondition(),  
         new ParamsRequestCondition(),  
         new HeadersRequestCondition(),  
         new ConsumesRequestCondition(),  
         new ProducesRequestCondition(),  
         customCondition);  
   }  
 }  

Annotation @ApiVersion akan dibaca valuenya berapa kemudian akan digabungkan dengan value @RequestMapping, sehingga bisa menjadi /v2/person /v1/person saat diload pertama kali oleh Spring. Jika controller tanpa menggunakan annotation akan tetap dibaca /person

3. Buat class WebMvcConfig

 @Component  
 public class WebMvcConfig extends WebMvcConfigurationSupport {  
   @Bean  
   @Override  
   public RequestMappingHandlerMapping requestMappingHandlerMapping() {  
     return new ApiVersionRequestMappingHandlerMapping("v");  
   }  
 }  

Semua RequestMapping yang menggunakan ApiVersion otomatis akan diawali dengan ''v''.

4. Hilangkan tag annotation-driven diServletContext.xml, gantikan dengan class WebMvcConfig yang sudah dibuat tadi.

 <!--  
 <annotation-driven />  
 -->  
 <beans:bean class="com.andri.sample.version.WebMvcConfig" />  

5. Buat controller person

 @Controller  
 public class HomeController {  
      private static final Logger logger = LoggerFactory.getLogger(HomeController.class);  
      
      @RequestMapping(value = "/person", method = RequestMethod.GET)  
      @ResponseBody  
      public ResponseEntity<String> getPerson(){  
           String result = "this is rest person api version 1";  
           return getJsonResponse(result, HttpStatus.OK);  
      }  

      @RequestMapping(value = "/person", method = RequestMethod.GET)  
      @ResponseBody  
      @ApiVersion(2)  
      public ResponseEntity<String> getPersonV2(){  
           String result = "this is rest person api version 2";  
           return getJsonResponse(result, HttpStatus.OK);  
      }  
      public static <T> ResponseEntity<T> getJsonResponse(T src, HttpStatus status) {  
           HttpHeaders headers = new HttpHeaders();  
           headers.set("Content-Type", MediaType.APPLICATION_JSON_VALUE);  
           return new ResponseEntity<T>(src, headers, status);  
      }  
 }  

6. Start spring application menggunakan jetty atau tomcat, atau application server lain.

Sekarang coba akses url rest nya : /person dan /v2/person

http://localhost:8080/sample/person


http://localhost:8080/sample/v2/person



referensi : http://stackoverflow.com/questions/20198275/how-to-manage-rest-api-versioning-with-spring
source-code : https://andri_khrisharyadi@bitbucket.org/andri_khrisharyadi/spring-rest-versioning.git

Selamat Mencoba.

Tuesday, September 16, 2014

REST Web Service Client menggunakan RestTemplate

Bagaimana untuk request ke sebuah Rest API dan mendapatkan hasilnya ?
Kalau di Java pada umumnya untuk memanggil ke Rest API digunakan class http client.

Misalnya ada Rest API seperti ini : http://host-01:8099/customer/271650
Return value berupa JSON seperti berikut ini :
 {  
 id: 271650,  
 name: "derp",  
 phone: "085635231",  
 email: "derp@herp.co.id",  
 corporateId: null,  
 voucherBalance: 0  
 }  

Nah, bagaimana caranya untuk mendapatkan data JSON tersebut agar bisa diolah lebih lanjut di class class lainnya.

Salah satu caranya kita bisa menggunakan class HttpURLConnection().
Berikut ini contohnya :
 package com.nostratech.app;  
 import java.io.BufferedReader;  
 import java.io.IOException;  
 import java.io.InputStreamReader;  
 import java.net.HttpURLConnection;  
 import java.net.MalformedURLException;  
 import java.net.URL;  
 public class SampleHttpClient {  
      public static void main(String[] args) {  
           try {  
                URL url = new URL(  
                          "http://host-01:8099/customer/271650/");  
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
                conn.setRequestMethod("GET");  
                conn.setRequestProperty("Accept", "application/json");  
                if (conn.getResponseCode() != 302 && conn.getResponseCode() != 200) {  
                     throw new RuntimeException("Failed : HTTP error code : "  
                               + conn.getResponseCode() + conn.getResponseMessage());  
                }  
                BufferedReader br = new BufferedReader(new InputStreamReader(  
                          (conn.getInputStream())));  
                String output;  
                System.out.println("JSON response : \n");  
                while ((output = br.readLine()) != null) {  
                     System.out.println(output);  
                }  
                conn.disconnect();  
           } catch (MalformedURLException e) {  
                e.printStackTrace();  
           } catch (IOException e) {  
                e.printStackTrace();  
           }  
      }  
 }  

Responsenya akan berupa string JSON, yang seperti ini.


Kemudian string json ini harus kita parsing manual satu per satu agar kita olah lagi.
Tentu hal ini akan terasa lebih rumit dan agak memakan waktu.

Salah satu cara untuk mempermudah request dan parsing json dari Rest API, adalah menggunakan library tambahan RestTemplate dari Spring Framework. Sebenarnya library ini digunakan di android project, tetapi bisa juga digunakan di Java project lainnya.

RestTemplate ini sudah mensupport hampir semua Http Method yang biasa digunakan di Rest API (POST, PUT, DELETE, GET dan lain-lain).

Langkahnya sangat mudah.
Tinggal tambahkan library (spring web dan core) ini ke java project kita (bisa didownload di sini ) :
spring-core-4.0.7.RELEASE.jar
spring-web-4.0.7.RELEASE.jar

Jangan lupa tambahkan juga library Jackson (download di sini). digunakan untuk parsing atau marshalling json resultnya.
jackson-annotations-2.3.2.jar (link)
jackson-core-2.3.2.jar (link)
jackson-mapper-asl-1.9.13.jar (link)

tambahkan class common-logging : commons-logging-1.1.3.jar (link)

Kita harus tahu dulu bagaimana format json responsenya. Kemudian dibuat class mappingnya (contohnya class : Customer) yang digunakan sebagai object hasil mapping json resultnya.
Atribut atributnya disamakan dengan json response, karena akan digunakan sebagai mapping
 package com.nostratech.app;  
 import java.math.BigDecimal;  
 public class Customer {  
      private Integer id;  
      private String name;  
      private String phone;  
      private String email;  
      private Integer corporateId;  
      private BigDecimal voucherBalance;  
      public Integer getId() {  
           return id;  
      }  
      public void setId(Integer id) {  
           this.id = id;  
      }  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      public String getPhone() {  
           return phone;  
      }  
      public void setPhone(String phone) {  
           this.phone = phone;  
      }  
      public String getEmail() {  
           return email;  
      }  
      public void setEmail(String email) {  
           this.email = email;  
      }  
      public Integer getCorporateId() {  
           return corporateId;  
      }  
      public void setCorporateId(Integer corporateId) {  
           this.corporateId = corporateId;  
      }  
      public BigDecimal getVoucherBalance() {  
           return voucherBalance;  
      }  
      public void setVoucherBalance(BigDecimal voucherBalance) {  
           this.voucherBalance = voucherBalance;  
      }  
      @Override  
      public String toString() {  
           return "Customer [id=" + id + ", name=" + name + ", phone=" + phone  
                     + ", email=" + email + ", corporateId=" + corporateId  
                     + ", voucherBalance=" + voucherBalance + "]";  
      }  
 }  

Kemudian kita buat class sample rest client.
Ditambahkan juga MessageConverter untuk convert dari json string ke object.
Kita gunakan MappingJackson2HttpMessageConverter() sebagai converternya.
 package com.nostratech.app;  
 import java.util.ArrayList;  
 import java.util.List;  
 import org.springframework.web.client.RestTemplate;  
 import org.springframework.http.converter.HttpMessageConverter;  
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;  
 public class SampleRestClient {  
      public static void main(String[] args) {  
           String url = "http://host-01:8099/customer/271650";  
           RestTemplate restTemplate = new RestTemplate();  
           List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();  
           messageConverters.add(new MappingJackson2HttpMessageConverter());  
           restTemplate.getMessageConverters().addAll(messageConverters);  
           Customer customer = restTemplate.getForObject(url, Customer.class);  
           System.out.println("Result customer : "+customer);  
      }  
 }  

Hasilnya kurang lebih akan seperti ini setelah di running.
Ouput json sudah menjadi object Customer.


Terima kasih, semoga membantu.

Selamat mencoba.



RESTful Web-Service dengan JAX-RS

REST (Representational State Transfer) merupakan gaya arsitektur web service berbasis protokol HTTP. Pertama kali diutarakan oleh Roy Fielding pada tesis nya di tahun 2000. REST di gunakan sebagai prinsip dasar untuk transfer data secara stateless pada data yang dapat di akses menggunakan protokol HTTP.

Pada arsitektur REST, data merupakan resource yang dapat di akses melalui metode-metode standar HTTP seperti GET, POST, PUT, DELETE. Masing-masing metode HTTP ini di gunakan untuk mendapatkan (retrieve) ataupun memanipulasi resource. GET digunakan untuk mengambil resource, PUT untuk menambah (insert) resource, POST digunakan untuk memodifikasi (update) resource, dan DELETE untuk membuang resource.

Tidak seperti SOAP yang mengharuskan memakai XML sebagai format data, dan memiliki struktur format yang tetap (fixed), setiap data pada REST dapat di representasikan dalam berbagai format, antara lain teks, XML, JSON, dll. Namun begitu JSON adalah format data yang paling sering di pakai pada implementasi web service menggunakan REST.

Beberapa keuntungan REST dibandingkan dengan SOAP adalah:
Lebih sederhana, hanya memakai protokol HTTP biasa, tidak memerlukan struktur data khusus.
Lebih Performa dan Scalable, hanya data saja yang di transfer tidak ada overhead seperti pada SOAP.

Hal ini tidaklah menjadikan REST lebih baik dari SOAP, dalam beberapa kasus, di mana komunikasi antar web service adalah stateful dan di haruskan berada dalam satu transaksi, SOAP lebih tepat untuk di gunakan karena sudah menyediakan fitur-fitur untuk meng-implementasikannya dengan mudah. Namun, jika anda ingin sekedar berbagi data secara sederhana atau membuat CRUD service (Create, Read, Update, Delete), maka REST merupakan pilihan yang lebih tepat.

Java men-support REST melalui JSR-311, yang di namakan JAX-RS (Java API for RESTful Web Services). Adapun reference implementation dari JAX-RS sendiri adalah Jersey. Beberapa implementasi lainnya adalah:
- Apache CXF
- RESTEasy (JBoss)
- Restlet

Saya akan menjelaskan cara membuat REST service sederhana menggunakan JAX-RS dengan bantuan Eclipse IDE dan Maven. Aplikasi yang di buat dengan JAX-RS dapat berjalan pada JavaEE application server maupun servlet container biasa, oleh karena itu, pembahasan langkah-langkah pembuatan di bagi berdasarkan konteks deployment nya. Sebagai contoh saya menggunakan Glassfish 3.1 dan Tomcat 7.

Persiapan

Eclipse IDE

Jika Eclipse IDE anda belum mempunyai Maven support, maka anda harus terlebih dahulu meng-install plugin m2e dan m2e-wtp, jika anda memakai Eclipse Juno seperti saya maka anda dapat memakai update site berikut:

m2e: http://download.eclipse.org/technology/m2e/releases
m2e-wtp: http://download.eclipse.org/m2e-wtp/releases/juno


Glassfish

Anda dapat mengunduh glassfish disini dan menginstall nya secara manual. Atau jika anda pengguna linux dapat menginstall melalui package manager sesuai distro masing-masing.

Install juga GlassFish Tools for Eclipse agar dapat menjalankan dan men-deploy aplikasi ke dari Eclipse. Untuk panduan instalasi bisa cek disini.

Tomcat

Anda dapat mengunduh tomcat disini dan menginstall nya secara manual. Atau jika anda pengguna linux dapat menginstall melalui package manager sesuai distro masing-masing.

Eclipse sudah men-support Tomcat out of the box jadi anda tidak perlu menginstall plugin khusus.

1. JavaEE Application Server - Glassfish

Seperti yang sudah di jelaskan di atas, Jersey adalah reference implementation dari JAX-RS. Jika anda menggunakan glassfish, maka Jersey sudah tersedia, karena JAX-RS merupakan bagian dari Java Enterprise Edition (JavaEE), dan glassfish adalah application server yang men-support penuh JavaEE dan menggunakan Jersey sebagai implementasi JAX-RS nya.

Pastikan plugin Maven untuk Eclipse & Glassfish sudah ter-install, jika belum ikuti tahap Persiapan di atas. Buat project maven baru dengan Eclipse:

File -> New -> Other -> Maven Project. Ketik "webapp" pada filter. Pilih maven-archtype-webapp pada hasil pencarian yang muncul di bawah nya.


Isi parameter project pada halaman selanjutnya dan klik Finish.


Tambahkan dependency ke JAX-RS API di pom.xml

<dependencies>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependencies>


Agar glassfish mengenali aplikasi kita sebagai aplikasi JAX-RS maka kita harus mambuat subclass yang meng-extend javax.ws.rs.core.Application serta meng-anotasi kan nya dengan @ApplicationPath


Untuk itu disini saya membuat class HelloApplication.java, yang saya berikan anotasi @ApplicationPath dengan parameter "/rest" di mana ini akan menjadi base url dari aplikasi

Tahap selanjutnya adalah membuat resource (dalam terminologi REST), yang merupakan service endpoint.

Buat class baru bernama HelloResource dengan isi sebagai berikut

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/{name}")
public String sayHello(@PathParam("name") String name) {
return "Hello, " + name;
}


}

Class ini memiliki method sayHello yang di berikan anotasi-anotasi JAX-RS. @GET berarti method ini akan me-respon pada get request. @PathParam & @Param merupakan satu kesatuan, nama parameter yang di berikan pada @PathParam harus persis sama dengan yang di letakkan pada @Path di dalam kurung-kurawal. @PathParam mengharapkan request yang datang memiliki parameter pada request path nya. Contoh, ketika client melakukan request ke "/rest/hello/world", "world" akan menjadi parameter untuk method sayHello@Produces menginstruksikan JAX-RS untuk membuat representasi sesuai format data yang di berikan, dalam kasus ini "plain text" atau teks biasa.


Yupz!, selesai sudah aplikasi JAX-RS kita yang sangat sederhana ini. Untuk men-deploy-nya ke glassfish klik kanan pada project -> Run As -> Run On Server -> Pilih Glassfish (Jika tidak terdapat pilihan seperti pada gambar maka anda harus membuatnya terlebih dahulu, dengan memilih "Manually define a new server")


Tampilan saat di jalankan:


2. Servlet Container - Tomcat

Jersey juga dapat bekerja sebagai servlet yang berjalan pada servlet container seperti Tomcat. Jersey akan meng-scan semua class yang sudah di definisikan sebagai RESTful resource, menganalisa HTTP request yang datang dan memilih class yang tepat untuk membuat response.

Pastikan plugin Maven untuk Eclipse & Tomcat sudah ter-install, jika belum ikuti tahap Persiapan di atas. Buat project maven baru dengan Eclipse:

File -> New -> Other -> Maven Project. Ketik "webapp" pada filter. Pilih maven-archtype-webapp pada hasil pencarian yang muncul di bawah nya.


Isi parameter project pada halaman selanjutnya dan klik Finish.


Tambahkan dependency ke Jersey Container Servlet di pom.xml

<dependencies>
    <dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.12</version>
<scope>compile</scope>

    </dependency>
</dependencies>

Setup Jersey sebagai servlet di web.xml

<servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>org.hello.rest</param-value>
</init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyApplication</servlet-name>
        <url-pattern>/rest/*</url-pattern>

    </servlet-mapping>

Jika anda perhatikan saya memberikan init parameter dengan nama jersey.config.server.provider.packages, dan memberikan value berupa package di mana class resource berada. Jersey akan melakukan scanning pada package ini dan me-register semua resource yang di dapat secara otomatis.


Lakukan langkah untuk membuat class resource HelloResource seperti yang terdapat pada langkah sebelumnya.

Aplikasi sudah siap untuk di deploy di Tomcat:



Saat anda jalankan anda akan mendapati hasil yang sama dengan saat menjalankannya di Glassfish:


Data dengan format JSON


Untuk membuat response dengan format data JSON di perlukan JAXB (Jaxa API for XML Binding).

Tambahkan dependency ke JAXB API di pom.xml

<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.1</version>
    <scope>provided</scope>
</dependency>

Sebagai contoh anda dapat membuat resource class dengan isi sebagai berikut:

@Path("/fruits")
public class FruitResource {

private final List<Fruit> fruits;

public FruitResource() {
fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Apple", 10.25));
fruits.add(new Fruit("Orange", 7.11));
fruits.add(new Fruit("Grape", 9.37));
}

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/list")
public List<Fruit> listFruits() {
return fruits;
}

@XmlRootElement()
static class Fruit {
String name;
double price;

public Fruit(){}

public Fruit(String name, double price){
this.name = name;
this.price = price;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}

Hasilnya saat di jalankan:


Sangat mudah bukan membuat RESTful service dengan JAX-RS :)

Demikian, semoga bermanfaat !

Convert SOAP ke REST & REST ke SOAP Menggunakan OSB Part 2

Lanjutan dari part 1...

  1. Sebelum melanjutkan proses, kita akan terlebih dahulu membuat XSLT script yang akan digunakan nanti pada proses transforming di dalam OSB. Buat XSLT dan beri nama xslt_1 & xslt_2 & xslt_add_namespace. Berikut code untuk xslt_1 :

    <xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
    <xsl:copy>
    <xsl:output indent="yes" /> <xsl:template match="@* | node()">
    <xsl:template match="soapenv:*">
    <xsl:apply-templates select="@* | node()" /> </xsl:copy> </xsl:template>
    </xsl:stylesheet>
    <xsl:apply-templates select="@* | node()" />
    </xsl:template>

    Berikut code untuk xslt_2 :

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="*"> <xsl:element name="{local-name()}">
    </xsl:template>
    <xsl:apply-templates select="@* | node()" /> </xsl:element> <xsl:template match="@*">
    </xsl:template>
    <xsl:attribute name="{local-name()}"> <xsl:value-of select="." /> </xsl:attribute>
    </xsl:stylesheet>
    <xsl:template match="text() | comment() | processing-instruction()"> <xsl:copy />
    </xsl:template>

    Berikut code untuk xslt_add_namespace :

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*"> <xsl:copy>
    </xsl:template>
    <xsl:apply-templates select="node()|@*" /> </xsl:copy> <xsl:template match="*">
    <xsl:apply-templates select="node()|@*" />
    <xsl:element name="inq:{local-name()}" namespace="www.nostratech.com/xsd/inquiry"> </xsl:element> </xsl:template>
    </xsl:stylesheet>

    Sedikit penjelasan, untuk melakukan convert dari SOAP ke REST kita harus terlebih dahulu membuang soap envelope & namespace yang ada dalam body SOAP menggunakan xslt_1 & xslt_2 sehingga hanya tersisa xml body yang diperlukan sebagai payload input untuk REST xml kita. Sedangkan untuk proses convert dari REST ke SOAP, kita memerlukan xslt_add_namespace untuk menambahkan namespace sebelum di passing kembali ke SOAP body.

  2. Langkah selanjutnya kita akan melakukan Routing & Transform pada Proxy Service yang telah kita buat. Klik Edit Message Flow, kemudian tambahkan pipeline air.


    Tambahkan Stage dimasing masing Request & Response Pipeline.


  3. Langkah selanjutnya ialah mengedit Stage yang ada dibagian Request terlebih dahulu. Klik edit stage. Tambahkan Assign sebanyak 2 buah.




  4. Jika sudah, pada Assign pertama, klik Expression, kemudian pilih XSLT Resource, pilih xslt_1 yang telah kita buat tadi. Pada bagian Input Document isi dengan :

     $body/inq:accountInquiryRequest  
    

    Kemudian klik Save. Setelah itu isi input variable nya dengan var1. Tujuan nya adalah menyimpan proses hasil xslt_1 yang diambil dari $body/inq:accountInquiryRequest ke var1.


  5. Pada Assign kedua, klik Expression, kemudian pilih XSLT Resource, pilih xslt_2 yang telah kita buat tadi. Pada bagian Input Document isi dengan :

     $var1  
    

    Kemudian klik Save. Setelah itu isi input variable dengan var2.


  6. Tambahkan Action dengan Service Callout.

    Klik Service, kemudian pilih Business Service yang telah kita buat tadi. Jika sudah maka tampilan nya akan seperti berikut :
    Pada bagian Request Document Variable isi dengan var2, dan pada bagian Response Document Variable isi dengan var3. Jika sudah Klik Save.


  7. Langkah selanjutnya ialah mengedit Stage yang ada dibagian Response. Klik Edit Stage. Tambahkan Assign sebanyak 2 buah.


  8. Pada Assign pertama, Klik Expression, kemudian pilih XSLT Resource, pilih xslt_1 yang telah kita buat tadi. Pada bagian Input Document isi dengan :

     $var3  
    

    Kemudian klik Save.

    Setelah itu isi input variablenya dengan var4.
  9. Pada Assign kedua, Klik Expression, kemudian pilih XSLT Resource, pilih xslt_add_namespace yang telah kita buat tadi. Pada bagian Input Document isi dengan :

     $var4  
    

    Kemudian klik Save.

    Setelah itu isi input variable nya dengan var5.
  10. Tambahkan Action Replace. Kemudian pada bagian XPath isi dengan :

     .  
    

    Kemudian Save.
    Pada bagian in Variable di isi dengan :

     body  
    

    Pada bagian with, di isi dengan :

     $var5  
    

    Kemudian pilih Replace Node Content.
    Jika sudah klik Save.

    Commit Session, kemudian bisa kita test.
  11. Ketika Test, bisa memakai contoh payload sebagai berikut :

     <inq:accountInquiryRequest xmlns:inq="http://www.nostratech.com/xsd/inquiry">  
       <inq:bankCode>123</inq:bankCode>  
       <inq:accountNo>1234567890</inq:accountNo>  
       <inq:accountCurrency>IDR</inq:accountCurrency>  
       <inq:messageId>1234567890</inq:messageId>  
       <inq:rqDatetime>2008-09-29T08:49:45</inq:rqDatetime>  
     </inq:accountInquiryRequest>  
    

    Kira kira hasilnya akan sepertinya ini.

     <soapenv:Envelope      xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
          <soap:Header      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
          </soap:Header>  
          <soapenv:Body>  
               <inq:accountInquiryRequest      xmlns:inq="www.nostratech.com/xsd/inquiry">  
                    <inq:bankCode>123</inq:bankCode>  
                    <inq:accountNo>1234567890</inq:accountNo>  
                    <inq:accountCurrency>IDR</inq:accountCurrency>  
                    <inq:messageId>1234567890</inq:messageId>  
                    <inq:rqDatetime>2008-09-29T08:49:45</inq:rqDatetime>  
               </inq:accountInquiryRequest>  
          </soapenv:Body>  
     </soapenv:Envelope>  
    

     
    Demikianlah cara untuk menconvert dari SOAP service ke REST & Menggembalikan REST ke SOAP. Semoga bermanfaat !!