Membuat RESTful Web Service Dengan Spring Data REST


Pada tulisan tentang web service sebelumnya, saya selalu menggunakan SOAP. Selain memakai SOAP, solusi yang kini populer adalah REST. Yup! Saya sering berpikir SOA telah terkubur karena mulai jarang diperbicarakan. Tapi ternyata masih ada buku baru Thomas Erl yang diterbitkan pada Agustus 2012 yang berjudul “SOA with REST: Principles, Patterns & Constraints for Building Enterprise Solutions with REST“.

Saya tidak akan membicarakan teori disini, tapi apa kelebihan REST? Bila SOAP adalah “early-binding” (bayangkan sebuah variabel dengan tipe data yang ketat dan sudah pasti!) maka REST adalah “late-binding” (bayangkan variabel generik tanpa tipe data seperti di JavaScript). REST lebih ringan karena bisa dipakai cukup dengan memanggil request HTTP. REST juga tidak perlu memakai WSDL untuk mengetahui kontrak servis! Loh, jika tidak ada WSDL, lalu bagaimana mengetahui layanan apa yang disediakan? REST mensyaratkan penggunaan URI dan Request Method yang harus dipatuhi. Sebagai contoh:

REST pada dasarnya adalah mengakses HTTP layaknya browsing.  Dengan demikian, tidak dibutuhkan “kode program” khusus.  Semua bahasa yang mendukung akses HTTP dapat memakai REST.  Yang membedakan REST adalah pada REST terdapat peraturan-peraturan yang harus “dipatuhi” sehingga komunikasi bisa berjalan lancar.

Walaupun demikian, REST bukanlah protokol seperti SOAP, sehingga “peraturan”-nya boleh dilanggar.  Hal ini dapat membingungkan client yang memakai.  Yup! Kadang-kadang sulit menjelaskan pada mahasiswa yang berharap menemukan kode program atau teknik baru yang mutakhir;  REST berhubungan dengan disiplin dan ‘manajemen’.  Mahasiswa yang berfokus pada membuat sistem untuk skripsi lalu meninggalkannya begitu saja setelah lulus akan sulit merasakan manfaatnya.

Saya akan mulai membuat RESTful web service dengan memakai Spring Data REST. Saya mulai dengan membuat sebuah proyek baru dengan memilih File, New, Spring Template Project di Spring Tool Suite (STS).  Pada dialog yang muncul, saya memilih Spring MVC Project dan men-klik tombol Next.  Saya mengisi nama proyek dengan rest-api dan lokasi package dengan com.jocki.rest.  Lalu, saya men-klik tombol Finish.

Setelah proyek selesai dibuat, saya me-double click file pom.xml untuk memastikan bahwa properties org.springframework-version minimal adalah versi 3.0. Selain itu, saya akan menambahkan dependency berikut ini:

  • org.hibernate : hibernate-entitymanager : 3.6.0.Final (sebagai JPA provider)
  • org.springframework.data : spring-data-jpa : 1.1.0.RELEASE
  • org.springframework : spring-tx : ${org.springframework-version}
  • org.springframework : spring-orm : ${org.springframework-version}
  • org.springframework.data : spring-data-rest-webmvc : 1.0.0.RELEASE
  • com.h2database : h2 : 1.3.167 (sebagai database in-memory)

Pada Package Explorer, saya men-klik kanan folder src/main/java, men-klik kanan dan memilih menu New, Class. Saya mengisi Package dengan com.jocki.domain, dan mengisi Name dengan Buku. Class ini akan mewakili domain class saya, dimana isi kode programnya adalah:

package com.jocki.domain;

import java.io.Serializable;

import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@Cacheable
public class Buku implements Serializable {

	private static final long serialVersionUID = 9099989372502423316L;

	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long id;

	private String judul;

	private String isbn;

	private Integer harga;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getJudul() {
		return judul;
	}

	public void setJudul(String judul) {
		this.judul = judul;
	}

	public String getIsbn() {
		return isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}

	public Integer getHarga() {
		return harga;
	}

	public void setHarga(Integer harga) {
		this.harga = harga;
	}

}

Untuk melakukan operasi persistensi (CRUD ke database embedded H2), saya akan menggunakan Spring Data JPA. Untuk itu, saya men-klik kanan pada folder src/main/java, kemudian memilih New, Interface. Pada Package, saya mengisi com.jocki.repository dan pada Name, saya mengisi BukuRepository. Kode program untuk interface tersebut akan terlihat seperti berikut ini:

package com.jocki.respository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.jocki.domain.Buku;

public interface BukuRepository extends JpaRepository<Buku, Long>{

}

Saya akan mulai dengan membuka folder src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml. Lalu, saya akan menambahkan definisi bean berikut ini:

<beans:bean class="org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration" />

Bean tersebut dibutuhkan untuk men-export seluruh repository saya secara otomatis sehingga operasi persistensi data pada domain object Buku dapat diakses melalui REST.

Berikutnya, saya perlu menyiapkan konfigurasi persistensi data. Saya akan mengubah file src/main/webapp/WEB-INF/spring/root-context.xml. Saya mendouble-click file ini, kemudian memilih tab Namespaces dan memastikan bahwa saya memberi tanda centang pada beans, context, jdbc, jpa, dan tx. Lalu saya menambahkan definisi berikut ini pada file root-context.xml:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
  <property name="entityManagerFactory" ref="emf" /> 
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
  </property> 
  <property name="packagesToScan" value="com.jocki.domain" /> 
  <property name="jpaProperties">
    <props>
      <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
      <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
      <prop key="hibernate.id.new_generator_mappings">true</prop>
    </props>
  </property>
</bean>
<context:annotation-config />
<context:component-scan base-package="com.jocki" />
<jpa:repositories base-package="com.jocki.repository" />
<jdbc:embedded-database id="dataSource" type="H2" />

Setelah ini, saya tinggal menjalankan tc Server.  Caranya adalah dengan men-klik kanan pada nama proyek, memilih menu Run As, Run on server.  Pada dialog yang muncul, saya memilih salah satu server yang tersedia, misalnya tc Server v2.7, lalu men-klik tombol Finish. Setelah server selesai dijalankan, browser secara otomatis akan terbuka pada URL http://localhost:8080/rest.

Spring Data REST mendukung HATEOAS (Hypermedia as the Engine of Application State) dimana terdapat links dari sebuah resource ke resource lainnya secara konsisten.  Yang muncul pertama kali di URL tersebut adalah seluruh daftar resource yang disediakan oleh Spring Data RESTseperti berikut ini:

{
  "links" : [ {
    "rel" : "buku",
    "href" : "http://localhost:8080/rest/buku"
  } ],
  "content" : [ ]
}

REST tidak mensyaratkan penggunaan format tertentu untuk konten.  Client dapat memilih format dengan menyertakan header Content-Type yang diinginkan seperti application/json atau application/xml.  Tapi untuk saat ini, Spring Data REST secara bawaan (tanpa perubahan!) hanya akan mengembalikan format application/json.

Untuk menguji REST, saya akan memakai tool curl.

Untuk melihat daftar seluruh resource “buku” yang ada di database,  saya perlu memberikan method GET pada URL http://localhost:8080/rest/buku seperti yang terlihat pada gambar berikut ini:

Memakai REST untuk melihat seluruh "buku" yang tersedia.

Operasi REST untuk melihat seluruh “buku” yang tersedia.

Karena saya menurunkan interface BukuRepository dari JpaRepository, maka secara otomatis saya memiliki fitur penghalamanan (paging).

Untuk melihat method apa saja yang didukung di RESTful web services, saya perlu memberikan request HTTP dengan method OPTIONS seperti yang terlihat pada gambar berikut ini:

Melihat operasi yang didukung oleh RESTful API

Melihat operasi yang didukung oleh RESTful API

Sekarang, saya akan menambah sebuah buku baru.  Untuk itu saya meng-hit URL dengan method POST seperti pada gambar berikut ini:

Membuat resource baru dengan REST

Membuat resource baru dengan REST

Saya terpaksa memberikan perintah tersebut di console Bash karena selalu gagal di console Windows.  Sekarang, bila saya melihat daftar “Buku” yang ada, saya akan menemukan hasil seperti pada gambar berikut ini:

Melihat seluruh "Buku" yang ada dengan REST

Melihat seluruh “Buku” yang ada dengan REST

Untuk menghapus buku dengan id 1, saya bisa melakukan request HTTP dengan method DELETE, seperti yang terlihat pada gambar berikut ini:

Menghapus resource dengan REST

Menghapus resource dengan REST

Perhatikan bahwa respon yang dikembalikan adalah 204 No Content, bukan 404 Not Found dan sebagainya.  Respon tersebut menunjukkan bahwa operasi hapus telah berhasil dilakukan dan tidak ada sesuatu yang perlu dikembalikan pada client.

Bagi yang ingin memakai tools berbasis GUI, bisa mencoba plugin Firefox seperti plugin RESTClient.  Tools ini mendukung authentication dengan OAuth2, sebuah pengamanan yang umum dipakai untuk RESTful web services.  Berikut ini adalah contoh tampilan plugin RESTClient di Firefox:

Tampilan plugin RESTClient di Firefox

Tampilan plugin RESTClient di Firefox

Pada prakteknya, tentu saja operasi REST tidak dipanggil melalui cURL atau plugin Firefox, melainkan oleh sistem lain atau aplikasi lain.  Hampir semua bahasa pemograman bisa melakukan request HTTP secara bawaan.   Beberapa bahkan sudah menyediakan akses REST secara mudah, misalnya Jersey di Java atau Zend_Rest_Client di PHP (yang ini  hanya mendukung XML dan banyak “melanggar” prinsip REST).  Seorang mahasiswa yang baru belajar mungkin akan bertanya, kenapa harus selalu melibatkan sistem lain?  Karena pada dasarnya web service dan SOA adalah mengenai komunikasi antar-sistem atau antar-program!  Penerapan pada sebuah sistem tunggal tanpa komunikasi cukup disebut SOP (Service Oriented Programming).

Spring Data REST memang mempermudah meng-export repository menjadi RESTful Web Services.  Tetapi RESTful Web Services tidak hanya berisi operasi CRUD saja, melainkan juga services (business logic).  Untuk mendapatkan kendali yang lebih penuh, RESTful API dapat dibuat dari Spring Web MVC controller yang telah dilengkapi annotation yang mendukung REST.

Perihal Solid Snake
I'm nothing...

One Response to Membuat RESTful Web Service Dengan Spring Data REST

  1. Ping-balik: LINK : Simple Tutorial RMI – REST | snippetjournal

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: