Membuat Layanan Mikro REST dengan Javalin

1. Perkenalan

Javalin adalah kerangka kerja web ringan yang ditulis untuk Java dan Kotlin. Ini ditulis di atas server web Jetty, yang membuatnya berkinerja tinggi. Javalin dimodelkan secara dekat dari koa.js, yang artinya ditulis dari awal agar mudah dipahami dan dikembangkan.

Dalam tutorial ini, kita akan memandu melalui langkah-langkah membangun layanan mikro REST dasar menggunakan kerangka kerja ringan ini.

2. Menambahkan Dependensi

Untuk membuat aplikasi dasar, kita hanya membutuhkan satu dependensi - Javalin itu sendiri:

 io.javalin javalin 1.6.1 

Versi saat ini dapat ditemukan di sini.

3. Menyiapkan Javalin

Javalin membuat pengaturan aplikasi dasar menjadi mudah. Kita akan mulai dengan mendefinisikan kelas utama kita dan menyiapkan aplikasi “Hello World” sederhana.

Mari buat file baru dalam paket dasar kita yang disebut JavalinApp.java .

Di dalam file ini, kami membuat metode utama dan menambahkan yang berikut ini untuk menyiapkan aplikasi dasar:

Javalin app = Javalin.create() .port(7000) .start(); app.get("/hello", ctx -> ctx.html("Hello, Javalin!"));

Kami membuat instance baru Javalin, membuatnya mendengarkan pada port 7000, dan kemudian memulai aplikasi.

Kami juga menyiapkan titik akhir pertama kami untuk mendengarkan permintaan GET di / hello endpoint.

Mari jalankan aplikasi ini dan kunjungi // localhost: 7000 / hello untuk melihat hasilnya.

4. Membuat UserController

Contoh "Halo Dunia" bagus untuk memperkenalkan topik, tetapi tidak bermanfaat untuk aplikasi nyata. Mari kita lihat kasus penggunaan yang lebih realistis untuk Javalin sekarang.

Pertama, kita perlu membuat model dari objek yang sedang kita kerjakan. Kami mulai dengan membuat paket yang disebut pengguna di bawah proyek root.

Kemudian, kami menambahkan kelas Pengguna baru :

public class User { public final int id; public final String name; // constructors }

Juga, kita perlu menyiapkan objek akses data (DAO) kita. Kami akan menggunakan objek dalam memori untuk menyimpan pengguna kami dalam contoh ini.

Kami membuat kelas baru dalam paket pengguna yang disebut UserDao.java:

class UserDao { private List users = Arrays.asList( new User(0, "Steve Rogers"), new User(1, "Tony Stark"), new User(2, "Carol Danvers") ); private static UserDao userDao = null; private UserDao() { } static UserDao instance() { if (userDao == null) { userDao = new UserDao(); } return userDao; } Optional getUserById(int id) { return users.stream() .filter(u -> u.id == id) .findAny(); } Iterable getAllUsernames() { return users.stream() .map(user -> user.name) .collect(Collectors.toList()); } }

Menerapkan DAO kami sebagai tunggal membuatnya lebih mudah digunakan dalam contoh. Kita juga bisa mendeklarasikannya sebagai anggota statis kelas utama kita atau menggunakan injeksi ketergantungan dari perpustakaan seperti Guice jika kita mau.

Akhirnya, kami ingin membuat kelas pengontrol kami. Javalin memungkinkan kita menjadi sangat fleksibel saat mendeklarasikan penangan rute kita, jadi ini hanya satu cara untuk mendefinisikannya.

Kami membuat kelas baru yang disebut UserController.java di paket pengguna :

public class UserController { public static Handler fetchAllUsernames = ctx -> { UserDao dao = UserDao.instance(); Iterable allUsers = dao.getAllUsernames(); ctx.json(allUsers); }; public static Handler fetchById = ctx -> { int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id"))); UserDao dao = UserDao.instance(); User user = dao.getUserById(id); if (user == null) { ctx.html("Not Found"); } else { ctx.json(user); } }; }

Dengan mendeklarasikan penangan sebagai statis, kami memastikan bahwa pengontrol itu sendiri tidak memiliki status. Namun, dalam aplikasi yang lebih kompleks, kita mungkin ingin menyimpan status di antara permintaan, dalam hal ini kita perlu menghapus pengubah statis.

Perhatikan juga bahwa pengujian unit lebih sulit dengan metode statis, jadi jika kita menginginkan tingkat pengujian itu, kita perlu menggunakan metode non-statis.

5. Menambahkan Rute

Kami sekarang memiliki banyak cara untuk mengambil data dari model kami. Langkah terakhir adalah mengekspos data ini melalui titik akhir REST. Kami perlu mendaftarkan dua rute baru di aplikasi utama kami.

Mari tambahkan mereka ke kelas aplikasi utama kita:

app.get("/users", UserController.fetchAllUsernames); app.get("/users/:id", UserController.fetchById);

Setelah menyusun dan menjalankan aplikasi, kita dapat membuat permintaan ke masing-masing titik akhir baru ini. Memanggil // localhost: 7000 / users akan mencantumkan semua pengguna dan memanggil // localhost: 7000 / users / 0 akan mendapatkan satu objek JSON Pengguna dengan id 0. Sekarang kita memiliki layanan mikro yang memungkinkan kita untuk mengambil data Pengguna .

6. Memperluas Rute

Mengambil data adalah tugas penting dari sebagian besar layanan mikro.

Namun, kita juga harus bisa menyimpan data di datastore kita. Javalin menyediakan set penangan jalur lengkap yang diperlukan untuk membangun layanan.

Kami melihat contoh GET di atas, tetapi PATCH, POST, DELETE, dan PUT juga dimungkinkan.

Selain itu, jika kita menyertakan Jackson sebagai dependensi, kita bisa mengurai badan permintaan JSON secara otomatis ke dalam kelas model kita. Misalnya:

app.post("/") { ctx -> User user = ctx.bodyAsClass(User.class); }

akan memungkinkan kita untuk mengambil objek Pengguna JSON dari badan permintaan dan menerjemahkannya ke dalam objek model Pengguna .

7. Kesimpulan

Kami dapat menggabungkan semua teknik ini untuk membuat layanan mikro kami.

Di artikel ini, kami melihat cara menyiapkan Javalin dan membangun aplikasi sederhana. Kami juga berbicara tentang cara menggunakan berbagai jenis metode HTTP agar klien dapat berinteraksi dengan layanan kami.

Untuk contoh lebih lanjut tentang bagaimana menggunakan Javalin, pastikan untuk memeriksa dokumentasinya.

Selain itu, seperti biasa, kode dapat ditemukan di GitHub.