Pengenalan RabbitMQ: Fungsionalitas, Instalasi dan Kasus Penggunaannya dengan Spring Boot 2

Jika pada artikel sebelumnya kita membahas tentang pengenalan RabbitMQ, Instalasi RabbitMQ dengan RabbitMQ Management Plugin maka pada artikel ini akan elanjutkan pembahasan dengan membahas tentang penggunaan RabbitMQ pada Spring Boot Project.

"Repository Kode Project Artikel Ini

Branch rabbit
Repo: https://github.com/yoesoff/YBoilerplate.git (fetch)"

Informasi tentang files, repo dan branch project artikel ini

Untuk mengintegrasikan RabbitMQ dalam proyek Spring Boot dengan file pom.xml yang sebelumnya (bila dari branch master repo saya atau dari project kosong springboot) berikan, kita perlu menambahkan beberapa dependensi yang relevan serta konfigurasi yang tepat.

1. Menambahkan Dependensi RabbitMQ ke pom.xml

Anda perlu menambahkan spring-boot-starter-amqp pada pom.xml untuk mendukung integrasi RabbitMQ. Ini adalah dependensi yang mendukung komunikasi AMQP (protocol yang digunakan oleh RabbitMQ).

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Setelah ditambahkan, ini akan memastikan Spring Boot bisa berinteraksi dengan RabbitMQ.

2. Menyiapkan Konfigurasi RabbitMQ

Anda dapat menambahkan konfigurasi untuk koneksi RabbitMQ di file application.properties atau application.yml di Spring Boot.

Sebagai contoh, jika Anda menggunakan application.properties:

spring.application.name=YBoilerplate
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=user
spring.rabbitmq.password=password

Konfigurasi ini mengatur koneksi RabbitMQ pada host localhost dengan port default 5672, dan menggunakan kredensial default guest/guest. Jika Anda menjalankan RabbitMQ pada kontainer Docker atau di server lain, sesuaikan dengan informasi yang sesuai.

Sekedar mengingatkan bahwa settingan di atas berasal dari kontainer yang kita buat berikut ini.


Ports forward (kiri adalah host windows kanan adalah dalam container)

User dan Password

Container Rabbit Sudah Jalan

Sampai sini saya berasumsi kita sudah memiliki container RabbitM yang berjalan, Pom.xml yang sudah ditambahkan dependency nya dan application.properties yang sudah berisi parameter yang tepat dan benar.

Jangan lupa reload Maven Project setelah dependency ditambahkan atau setiap pom diupdate.

Reload maven dependencies


3. Membuat Listener (Consumer)

Setelah dependensi dan konfigurasi siap, kita bisa membuat Listener untuk menerima pesan dari RabbitMQ. Sebagai contoh:

package com.mhyusuf.yboilerplate.service;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class RabbitMQListener {

@RabbitListener(queues = "your-queue-name")
public void listen(String message) {
System.out.println("Received message: " + message);
}
}

Listener ini akan menunggu pesan di antrian your-queue-name dan akan menangani pesan tersebut saat diterima.

4. Mengirim Pesan ke RabbitMQ (Producer)

Anda juga bisa mengirim pesan ke RabbitMQ menggunakan RabbitTemplate:

package com.mhyusuf.yboilerplate.service;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RabbitMQSender {

@Autowired
private RabbitTemplate rabbitTemplate;

public void send(String message) {
rabbitTemplate.convertAndSend("your-exchange-name", "your-routing-key", message);
}
}

Kelas ini akan mengirim pesan ke exchange tertentu dengan routing-key yang sudah ditentukan.

5. Konfigurasi Antrian, Exchange, dan Binding

Di dalam Spring Boot, Anda juga bisa mengkonfigurasi antrian, exchange, dan binding dengan cara berikut:

package com.mhyusuf.yboilerplate.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

@Bean
public Queue queue() {
return new Queue("myQueue", false);
}

@Bean
public DirectExchange exchange() {
return new DirectExchange("myExchange");
}

@Bean
public Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("myRoutingKey");
}
}


Ini adalah penambahan dan semua perubahan yang kita lakukan sejauh ini

6. Coba Jalankan Aplikasi

Setelah semuanya siap, Anda bisa menjalankan aplikasi Spring Boot Anda. Pastikan RabbitMQ sudah berjalan, baik secara lokal atau di dalam Docker.

Dengan semua langkah ini, Spring Boot Anda akan siap untuk berkomunikasi dengan RabbitMQ. 

7. Pindahkan beberapa value ke application.properties

Ya, memindahkan nilai seperti your-queue-name, your-exchange-name, dan your-routing-key ke dalam file properti seperti application.properties atau application.yml adalah best practice dalam pengembangan aplikasi Spring Boot, terutama untuk menjaga konfigurasi agar lebih dinamis dan mudah dikelola. Berikut adalah alasan dan cara melakukannya.

Alasan untuk Memindahkan ke File Properti:

  1. Pengelolaan yang Lebih Mudah: Memindahkan nilai-nilai ini ke file properti memudahkan pengelolaan konfigurasi di berbagai lingkungan (dev, staging, production) tanpa perlu memodifikasi kode sumber. Anda hanya perlu mengubah file properti sesuai dengan lingkungan.

  2. Prinsip Separation of Concerns: Dengan memisahkan konfigurasi dari logika bisnis, Anda memisahkan tanggung jawab antara kode aplikasi dan pengaturan, sehingga aplikasi lebih mudah dipelihara dan dikembangkan.

  3. Kemudahan dalam Deployment: Saat mengubah pengaturan seperti nama antrian atau exchange, Anda tidak perlu merilis ulang aplikasi; cukup perbarui file properti sesuai dengan kebutuhan.

  4. Keamanan dan Konsistensi: Mengelola pengaturan sensitif, seperti nama antrian atau key, dalam file properti yang bisa dienkripsi atau dikendalikan dengan alat manajemen konfigurasi (seperti Spring Cloud Config) lebih aman dan konsisten.

Implementasi

Tambahkan Pengaturan di application.properties atau application.yml

rabbitmq.queue.name=myPrettyQueue
rabbitmq.exchange.name=myPrettyExchange
rabbitmq.routing.key=myPrettyRoutingKey

Berikut adalah penjelasan dengan properti yang diperbarui:

  1. rabbitmq.queue.name=myPrettyQueue:

    • Antrian ini sekarang diberi nama myPrettyQueue. Semua pesan yang dikirim dan sesuai dengan konfigurasi ini akan disimpan dalam antrian tersebut. Konsumer yang mendengarkan myPrettyQueue akan mengambil pesan-pesan dari antrian ini.
  2. rabbitmq.exchange.name=myPrettyExchange:

    • Exchange bertanggung jawab untuk menerima pesan dari produsen dan meneruskannya ke antrian berdasarkan routing key. Dalam hal ini, exchange yang digunakan adalah myPrettyExchange. Seperti sebelumnya, jenis exchange (seperti direct, fanout, atau topic) tidak ditentukan dalam properti ini, namun namanya dapat digunakan dalam pengaturan di kode atau konfigurasi lebih lanjut.
  3. rabbitmq.routing.key=myPrettyRoutingKey:

    • Routing key digunakan oleh exchange untuk memutuskan antrian mana yang akan menerima pesan. Dengan myPrettyRoutingKey, pesan yang dikirimkan melalui myPrettyExchange akan diarahkan ke antrian yang sesuai, dalam hal ini bisa jadi myPrettyQueue (jika ada aturan binding yang menghubungkan keduanya dengan routing key tersebut).

Penjelasan:

  • Pesan yang dikirimkan ke myPrettyExchange akan menggunakan myPrettyRoutingKey untuk diarahkan ke myPrettyQueue.
  • Konfigurasi ini memudahkan pengelolaan komponen RabbitMQ secara terpisah, menjadikan aplikasi lebih fleksibel untuk diubah-ubah tanpa perlu mengedit kode sumber.

Kemudian Gunakan value di dalam Kode Spring Boot:

Anda bisa menggunakan anotasi @Value atau lebih baik lagi, menggunakan @ConfigurationProperties untuk mendapatkan nilai dari file properti tersebut.

Update RabbitMQSender untuk Menggunakan @Value:

package com.mhyusuf.yboilerplate.service;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class RabbitMQSender {

@Value("${rabbitmq.queue.name}")
private String queueName;

@Value("${rabbitmq.exchange.name}")
private String exchangeName;

@Value("${rabbitmq.routing.key}")
private String routingKey;

@Autowired
private RabbitTemplate rabbitTemplate;

public void send(String message) {
rabbitTemplate.convertAndSend(exchangeName, routingKey, message);
}
}

Update RabbitMQConfig untuk Menggunakan @Value:

package com.mhyusuf.yboilerplate.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

// Inject properties from application.properties
@Value("${rabbitmq.queue.name}")
private String queueName;

@Value("${rabbitmq.exchange.name}")
private String exchangeName;

@Value("${rabbitmq.routing.key}")
private String routingKey;

// Define the queue
@Bean
public Queue myQueue() {
return new Queue(queueName);
}

// Define the exchange
@Bean
public TopicExchange myExchange() {
return new TopicExchange(exchangeName);
}

// Define the binding between the queue and exchange using the routing key
@Bean
public Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(routingKey);
}
}

Update RabbitMQListener untuk Menggunakan @Value:

package com.mhyusuf.yboilerplate.service;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class RabbitMQListener {

// Inject the queue name from the properties file
@Value("${rabbitmq.queue.name}")
private String queueName;

// Method to listen for messages from the specified queue
@RabbitListener(queues = "${rabbitmq.queue.name}")
public void listen(String message) {
System.out.println("Received message from queue " + queueName + ": " + message);
}
}

Penjelasan:

  • @Value("${rabbitmq.queue.name}"): Mengambil nilai dari properti rabbitmq.queue.name yang didefinisikan di application.properties.
  • Queue: Membuat queue menggunakan nama dari properti rabbitmq.queue.name.
  • TopicExchange: Membuat exchange menggunakan nama dari properti rabbitmq.exchange.name.
  • Binding: Menghubungkan queue dengan exchange menggunakan routing key yang ditentukan di properti rabbitmq.routing.key.

Dengan pendekatan ini, konfigurasi RabbitMQ menjadi lebih fleksibel karena dapat dengan mudah diubah melalui file konfigurasi tanpa perlu mengubah kode.

Memindahkan konfigurasi seperti nama antrian, exchange, dan routing key ke file properti adalah best practice yang memudahkan pemeliharaan, meningkatkan fleksibilitas, serta mendukung prinsip separation of concerns. Selain itu, pendekatan ini akan membuat aplikasi Anda lebih modular dan mudah di-deploy di berbagai lingkungan tanpa memodifikasi kode.

Setelah semuanya siap, Anda bisa menjalankan ulang aplikasi Spring Boot Anda. Pastikan RabbitMQ sudah berjalan tidak ada error code, maupun salah import.

8. Membuat REST APIs

REST Controller sederhana di Spring Boot untuk mendemonstrasikan cara kerja RabbitMQ. Rest controller ini akan menyediakan endpoint HTTP untuk mengirim pesan ke RabbitMQ dan menerima pesan dari RabbitMQ.

Berikut adalah contoh implementasi REST Controller sederhana untuk mendemonstrasikan pengiriman dan penerimaan pesan melalui RabbitMQ:

Langkah-langkah Implementasi:

Buat REST Controller

REST Controller ini akan menyediakan endpoint untuk mengirim pesan dan menerima pesan dari RabbitMQ.

package com.mhyusuf.yboilerplate.controller;

import com.mhyusuf.yboilerplate.service.RabbitMQSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/rabbitmq")
public class RabbitMQController {

@Autowired
private RabbitMQSender rabbitMQSender;

// Endpoint untuk mengirim pesan
@PostMapping("/send")
public String sendMessage(@RequestBody String message) {
rabbitMQSender.send(message);
return "Message sent to RabbitMQ: " + message;
}
}

10. Uji Coba dengan melakukan Request

Cara mengetes endpoint diatas dengan menggunakan curl:

curl -X POST -d "Hello RabbitMQ" http://localhost:8080/rabbitmq/send


Cara mengetes endpoint diatas dengan menggunakan Postman:

Mencoba membuat POST request dari Postman


Comments

Popular posts from this blog

Numpang Kerja Remote dari Bandung Creative Hub

Numpang Kerja Remote dari Bandung Digital Valley

Cara Decompile berkas Dex dan Apk Android