Pengantar Ratpack

1. Ikhtisar

Ratpack adalah sekumpulan pustaka berbasis JVM yang dibangun untuk aplikasi real-time berkinerja tinggi modern. Ini dibangun di atas mesin jaringan yang digerakkan oleh peristiwa Netty tertanam dan sepenuhnya sesuai dengan pola desain reaktif.

Di artikel ini, kita akan belajar bagaimana menggunakan Ratpack dan kita akan membuat aplikasi kecil menggunakannya.

2. Mengapa Ratpack?

Keunggulan utama Ratpack:

  • sangat ringan, cepat, dan dapat diskalakan
  • itu mengkonsumsi lebih sedikit memori daripada kerangka kerja lain seperti DropWizard; Hasil perbandingan benchmark yang menarik bisa dilihat disini
  • karena dibangun di atas Netty , Ratpack benar-benar digerakkan oleh peristiwa dan bersifat non-pemblokiran
  • itu memiliki dukungan untuk manajemen ketergantungan Guice
  • Sama seperti Spring Boot , Ratpack memiliki pustaka pengujian sendiri untuk menyiapkan kasus uji dengan cepat

3. Membuat Aplikasi

Untuk memahami cara kerja Ratpack, mari kita mulai dengan membuat aplikasi kecil dengannya.

3.1. Dependensi Maven

Pertama, mari tambahkan dependensi berikut ke pom.xml kita :

 io.ratpack ratpack-core 1.4.5   io.ratpack ratpack-test 1.4.5 

Anda dapat memeriksa versi terbaru di Maven Central.

Perhatikan bahwa meskipun kami menggunakan Maven sebagai sistem build kami, sesuai rekomendasi Ratpack, lebih baik menggunakan Gradle sebagai alat build karena Ratpack memiliki dukungan Gradle kelas satu yang disediakan melalui plugin Gradle Ratpack.

Kita dapat menggunakan skrip Gradle build berikut:

buildscript { repositories { jcenter() } dependencies { classpath "io.ratpack:ratpack-gradle:1.4.5" } } apply plugin: "io.ratpack.ratpack-java" repositories { jcenter() } dependencies { testCompile 'junit:junit:4.11' runtime "org.slf4j:slf4j-simple:1.7.21" } test { testLogging { events 'started', 'passed' } } 

3.2. Membangun Aplikasi

Setelah manajemen build kami dikonfigurasi, kami perlu membuat kelas untuk memulai server Netty tertanam dan membangun konteks sederhana untuk menangani permintaan default:

public class Application { public static void main(String[] args) throws Exception { RatpackServer.start(server -> server.handlers(chain -> chain .get(ctx -> ctx.render("Welcome to Baeldung ratpack!!!")))); } }

Seperti yang bisa kita lihat, dengan menggunakan RatpackServer kita sekarang dapat memulai server (port default 5050). Metode handlers () mengambil fungsi yang menerima objek Chain, yang memetakan semua permintaan yang masuk. "Handler Chain API" ini digunakan untuk membangun strategi penanganan respons.

Jika kita menjalankan cuplikan kode ini dan menekan browser di // localhost: 5050, “Selamat datang di Baeldung ratpack !!!” harus ditampilkan.

Demikian pula, kita dapat memetakan permintaan HTTP POST.

3.3. Menangani Parameter Jalur URL

Dalam contoh berikutnya, kita perlu menangkap beberapa parameter jalur URL di aplikasi kita. Di Ratpack kami menggunakan PathTokens untuk menangkapnya:

RatpackServer.start(server -> server .handlers(chain -> chain .get(":name", ctx -> ctx.render("Hello " + ctx.getPathTokens().get("name") + " !!!"))));

Di sini, kami memetakan parameter URL nama . Kapanpun permintaan seperti // localhost: 5050 / John akan datang, responnya adalah “Hello John !!!”.

3.4. Modifikasi Header Permintaan / Respon Dengan / Tanpa Filter

Terkadang, kita perlu memodifikasi header respon HTTP inline berdasarkan kebutuhan kita. Ratpack memiliki MutableHeaders untuk menyesuaikan respons keluar.

Misalnya, kita perlu mengubah tajuk berikut dalam respons: Access-Control-Allow-Origin , Accept-Language , dan Accept-Charset :

RatpackServer.start(server -> server.handlers(chain -> chain.all(ctx -> { MutableHeaders headers = ctx.getResponse().getHeaders(); headers.set("Access-Control-Allow-Origin", "*"); headers.set("Accept-Language", "en-us"); headers.set("Accept-Charset", "UTF-8"); ctx.next(); }).get(":name", ctx -> ctx .render("Hello " + ctx.getPathTokens().get("name") + "!!!"))));

Dengan menggunakan MutableHeaders yang kami tetapkan adalah menyetel tiga header dan mendorongnya ke dalam Chain .

Dengan cara yang sama, kita juga dapat memeriksa header permintaan yang masuk:

ctx.getRequest().getHeaders().get("//TODO")

Hal yang sama dapat dicapai dengan membuat filter. Ratpack memiliki antarmuka Penangan , yang dapat diimplementasikan untuk membuat filter. Ini hanya memiliki satu metode handle (), yang mengambil Konteks saat ini sebagai parameter:

public class RequestValidatorFilter implements Handler { @Override public void handle(Context ctx) throws Exception { MutableHeaders headers = ctx.getResponse().getHeaders(); headers.set("Access-Control-Allow-Origin", "*"); ctx.next(); } }

Filter ini dapat kita gunakan dengan cara berikut:

RatpackServer.start( server -> server.handlers(chain -> chain .all(new RequestValidatorFilter()) .get(ctx -> ctx.render("Welcome to baeldung ratpack!!!")))); }

3.5. JSON Parser

Ratpack secara internal menggunakan jackson yang lebih cepat untuk penguraian JSON. Kita dapat menggunakan modul Jackson untuk mengurai objek apa pun ke JSON.

Mari buat kelas POJO sederhana yang akan digunakan untuk parsing:

public class Employee { private Long id; private String title; private String name; // getters and setters }

Di sini, kami telah membuat satu kelas POJO sederhana bernama Karyawan , yang memiliki tiga parameter: id, judul , dan nama . Sekarang kita akan menggunakan objek Employee ini untuk diubah menjadi JSON dan mengembalikan hal yang sama ketika URL tertentu dipukul:

List employees = new ArrayList(); employees.add(new Employee(1L, "Mr", "John Doe")); employees.add(new Employee(2L, "Mr", "White Snow")); RatpackServer.start( server -> server.handlers(chain -> chain .get("data/employees", ctx -> ctx.render(Jackson.json(employees)))));

Seperti yang bisa kita lihat, kita secara manual menambahkan dua objek Employee ke dalam daftar dan menguraikannya sebagai JSON menggunakan modul Jackson . Segera setelah URL / data / karyawan ditemukan , objek JSON akan dikembalikan.

Poin yang perlu diperhatikan di sini adalah bahwa kami tidak menggunakan ObjectMapper sama sekali karena modul Ratpack Jackson akan melakukan hal yang diperlukan dengan cepat.

3.6. Database Dalam Memori

Ratpack has the first class support for in-memory databases. It uses HikariCP for JDBC connection pooling. In order to use it, we need to add Ratpack's HikariCP module dependency in the pom.xml:

 io.ratpack ratpack-hikari 1.4.5 

If we are using Gradle, the same needs to be added in the Gradle build file:

compile ratpack.dependency('hikari')

Now, we need to create an SQL file with table DDL statements so that the tables are created as soon as the server is up and running. We'll create the DDL.sql file in the src/main/resources directory and add some DDL statements into it.

Since we're using H2 database, we have to add dependencies for that too.

Now, by using HikariModule, we can initialize the database at the runtime:

RatpackServer.start( server -> server.registry(Guice.registry(bindings -> bindings.module(HikariModule.class, config -> { config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource"); config.addDataSourceProperty("URL", "jdbc:h2:mem:baeldung;INIT=RUNSCRIPT FROM 'classpath:/DDL.sql'"); }))).handlers(...));

4. Testing

Seperti yang disebutkan sebelumnya, Ratpack memiliki dukungan kelas satu untuk kasus pengujian jUnit. Dengan menggunakan MainClassApplicationUnderTest, kita dapat dengan mudah membuat kasus uji dan menguji titik akhir:

@RunWith(JUnit4.class) public class ApplicationTest { MainClassApplicationUnderTest appUnderTest = new MainClassApplicationUnderTest(Application.class); @Test public void givenDefaultUrl_getStaticText() { assertEquals("Welcome to baeldung ratpack!!!", appUnderTest.getHttpClient().getText("/")); } @Test public void givenDynamicUrl_getDynamicText() { assertEquals("Hello dummybot!!!", appUnderTest.getHttpClient().getText("/dummybot")); } @Test public void givenUrl_getListOfEmployee() throws JsonProcessingException { List employees = new ArrayList(); ObjectMapper mapper = new ObjectMapper(); employees.add(new Employee(1L, "Mr", "John Doe")); employees.add(new Employee(2L, "Mr", "White Snow")); assertEquals(mapper.writeValueAsString(employees), appUnderTest.getHttpClient().getText("/data/employees")); } @After public void shutdown() { appUnderTest.close(); } }

Harap perhatikan bahwa kita perlu menghentikan instance MainClassApplicationUnderTest yang sedang berjalan secara manual dengan memanggil metode close () karena metode ini mungkin memblokir sumber daya JVM secara tidak perlu. Itulah mengapa kami menggunakan anotasi @After untuk secara paksa menghentikan instance setelah kasus uji dijalankan.

5. Kesimpulan

Di artikel ini, kami melihat kesederhanaan menggunakan Ratpack.

Seperti biasa, kode sumber lengkap tersedia di GitHub.