Spring Boot for NATS enables declarative abstractions for implementing NATS in Spring Boot applications.
TIP: This project is inspired by Spring Kafka and Spring Pulsar and thus tries to closely match their implementation style.
-
Add
nats-spring-boot-starter
dependency to yourpom.xml
file:<dependency> <groupId>dev.all-things.boot</groupId> <artifactId>nats-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency>
-
Add
@EnableNats
on your Spring Boot application / configuration class.@EnableNats @Configuration(proxyBeanMethods = false) public class NatsConfiguration { @Bean @ConditionalOnMissingBean public NatsConnectionConfiguration natsConnectionConfiguration() { NatsConnectionConfiguration configuration = new NatsConnectionConfiguration(); configuration.setServers(List.of("nats://0.0.0.0:58811")); configuration.setUsername("local"); configuration.setPassword("dH...yu"); return configuration; } }
-
Create a listener class and annotate listener method with
@NatsListener
and the subject.
-
Simple listener
@Component public class MessageListener { @NatsListener(subject = "zion.neo") public void onMessage(String message) { logger.info("Received message: {}", message); // Hello, Neo } }
-
Listener with reply
@Component public class MessageListener { @NatsListener(subject = "zion.neo", reply = @Reply(subject = "zion.trinity")) public String onMessage(String message) { logger.info("Received message: {}", message); // Hello, Neo return "Hello, Trinity"; // Sent to the subject 'zion.trinity' } }
TIP: Listener methods support
io.nats.client.Message
,java.lang.String
andbyte[]
as reply types. However, user needs to explicitly set subject for the reply typeio.nats.client.Message
and the value set via annotation will be ignored. -
Listener with an unspecified reply type
@NatsListener(subject = "matrix.smith", reply = @Reply(subject = "matrix")) public Object onMessageWithGenericReply(final String message) { logger.info("Received message: {}", message); return switch (new Random(System.nanoTime()).nextInt(3)) { case 0 -> "Hello - From The Matrix"; case 1 -> UUID.randomUUID().toString(); default -> "Hello - From The Matrix".getBytes(StandardCharsets.UTF_8); }; }
TIP: A special handler will be created for listener methods with an unspecified return type which may be slightly inefficient. Also, error related to unsupported return types will be thrown at runtime. Use this feature only when necessary.
Certain attributes of the incoming message can be implicitly extracted and injected as parameters to the listener method.
-
@Header
allows single message header to be injected to the annotated parameter.@Headers
injects all message headers asMap<String, String>
.@Component public class MessageListener { @NatsListener(subject = "zion.trinity") public void onMessage(Message message, String messageContent, @Header("id") String messageId, @Headers Map<String, String> headers) { logger.info("Received message '{}', content '{}', id '{}', headers '{}'", message, messageContent, messageId, headers); } }
TIP: Headers can also be injected in multi-value format i.e.
Map<String, List<String>
.Map<String, String>
serves simple use-cases where headers are expected to have single value. -
Unannotated parameters of types
io.nats.client.Message
,java.lang.String
and/orbyte[]
are automatically treated as message content and injected accordingly.
- For better performance,
MethodHandle.invoke
is used (instead ofMethod.invoke
) for invoking the listener methods.
- JDK 17
- Spring Boot 3.2
This project is Open Source software released under the Apache 2.0 license.