Skip to content

Commit 16a04f5

Browse files
committed
API - Guide documentation complemented
1 parent f265b20 commit 16a04f5

File tree

1 file changed

+213
-15
lines changed

1 file changed

+213
-15
lines changed

docs/asciidoc/api-guide.adoc

Lines changed: 213 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ The project uses https://github.com/reactor/reactor-core[Reactor Core] to expose
1414

1515
=== Semantic Messages Classes
1616

17-
Reactice Commons has 2 classes that represent events or commands, it give it a semantic meaning for a message. So, let talks about DomainEvent and Command classes .
17+
Reactice Commons has 3 classes that represent events, commands or queries, giving a semantic meaning for a message. So, let's talk about DomainEvent and Command classes .
1818

1919
==== DomainEvent<T>
2020

21-
This class let you represent a Event in the system. It accepts a generic class that will be the information to transport for that event, a eventId and a name for the event. The structure for a DomainEvent is:
21+
:This class lets you represent a Event in the system. It accepts a generic class that will be the information to transport for that event, a eventId and a name for the event. The structure for a DomainEvent is
2222

2323
[source,java]
2424
--------
@@ -42,7 +42,7 @@ public class DomainEvent<T> {
4242

4343
==== Command<T>
4444

45-
An other basic structure is the Command class. This class let you represent a Command/Request in the system. It accepts a generic class that will be the information for that command, a eventId and a name for that event. The structure for a DomainEvent is:
45+
An other basic structure is the Command class. This class lets you represent a Command in the system. It accepts a generic class that will be the information for that command, a commandId and a name for that event. The structure for a Command is:
4646

4747
[source,java]
4848
--------
@@ -61,7 +61,21 @@ public class Command<T> {
6161
}
6262
--------
6363

64-
=== Reactive Commons - Sending Events and Commands
64+
==== AsyncQuery<T>
65+
66+
An other basic structure is the AsyncQuery class. This class lets you represent a Query in the system. It accepts a generic class that will be the information for that query and a name for that resoruce. The structure is:
67+
68+
69+
[source,java]
70+
--------
71+
@Data
72+
public class AsyncQuery<T> {
73+
private final String resource;
74+
private final T queryData;
75+
}
76+
--------
77+
78+
=== Reactive Commons - Sending Events, Commands and Request/Reply messages
6579

6680
Outbound messages are sent to an event bus using `DomainEventBus` or `DirectAsyncGateway` classes. If you are using Spring Boot, you can have a Main class like this:
6781

@@ -73,6 +87,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
7387
7488
@SpringBootApplication
7589
@EnableDomainEventBus
90+
@EnableDirectAsyncGateway
7691
public class MainApplication {
7792
public static void main(String[] args) {
7893
SpringApplication.run(MainApplication.class, args);
@@ -86,7 +101,9 @@ public class MainApplication {
86101
}
87102
--------
88103

89-
The @EnableDomainEventBus annotation enable to the application to emit Events to the System. This annotation create a EnableDomainEventBus Bean, so you can use it for emit events. This interface looks like:
104+
==== DomainEventBus
105+
106+
The @EnableDomainEventBus annotation enable to the application to emit Events to the System. This annotation create a EnableDomainEventBus bean, so you can use it for emitting events. This interface looks like:
90107

91108
[source,java]
92109
--------
@@ -99,28 +116,209 @@ public interface DomainEventBus {
99116
}
100117
--------
101118

102-
The emit method recive a DomainEvent<T> class where you can publish information to the system. The method will respond you in a reacive way with a Publisher, like a Mono or a Flux object. So, for example, if you want to send a UserRegistered event to the system ,you have to us
103-
119+
The emit method recive a DomainEvent<T> class where you can publish information to the system. The method will respond you in a reacive way with a Publisher, like a mono object. So, for example, if you want to send a UserRegistered event to the system ,you can do this:
104120

105121
[source,java]
106122
--------
107123
108124
public class AnyUseCase {
109125
110-
private DomainEventBus eventBus;
126+
private DomainEventBus eventBus; // Injected
111127
112-
public ManageTasksUseCase( DomainEventBus eventBus) {
113-
this.eventBus = eventBus;
128+
private Mono<Void> emitCreatedEvent(UserRegistered event) {
129+
return Mono.from(eventBus.emit(new DomainEvent<>("user.registered", uuid(), event)));
114130
}
131+
//...
132+
}
133+
--------
134+
135+
==== DirectAsyncGateway - Commands
136+
137+
If you want to send Commands to the system, the @EnableDirectAsyncGateway annotation enable to the application to emit Commands to the System. This annotation create a DirectAsyncGateway bean, so you can use it for emitting commands. This interface looks like:
115138

116-
public Mono<TaskToDo> doSomething(String name, String description) {
117-
return doSomething()
118-
.flatMap(task -> emitCreatedEvent(task).thenReturn(task));
139+
[source,java]
140+
--------
141+
public interface DirectAsyncGateway {
142+
<T> Mono<Void> sendCommand(Command<T> command, String targetName);
143+
<T, R> Mono<R> requestReply(AsyncQuery<T> query, String targetName, Class<R> type);
144+
}
145+
--------
146+
147+
The sendCommand method recive a Command<T> class where you can publish information to the system. The method will respond you in a reacive way with a Publisher, like a mono object. So, for example, if you want to send a UserRegister command to the "target.name" component ,you can do this:
148+
149+
[source,java]
150+
--------
151+
152+
public class AnyUseCase {
153+
154+
private DirectAsyncGateway gateway; // Injected
155+
156+
private Mono<Void> emitCreatedEvent(UserRegister command) {
157+
return gateway.sendCommand(new Command<>("user.register", uuid(), command), "target.name") // Continue reactive flow
119158
}
159+
//...
160+
}
161+
--------
120162

121-
private Mono<Void> emitCreatedEvent(EventClass event) {
122-
return Mono.from(eventBus.emit(new DomainEvent<>("name.event", uuid(), event)));
163+
The second parameter for sendCommand method is the name of the target component for that command, It's the name stablished in the properties file of Spring "application.properties" in the "spring.application.name" field.
164+
165+
[NOTE]
166+
you don't need this parameter in the emit method of DomainEventBus class, because an event is a fact for cero or more subscribers.
167+
168+
==== DirectAsyncGateway - Request/Reply
169+
170+
The DirectAsyncGateway class has another method called "requestReply", this method lets you to send a query and wait for an answer for that query. The method will respond you in a reacive way with a Publisher, like a mono object with the generic data. So, for example, if you want to send a query with QueryUser data, to the "target.name" component and recive an User object response, you can do this:
171+
172+
[source,java]
173+
--------
174+
175+
public class AnyUseCase {
176+
177+
private DirectAsyncGateway gateway; // Injected
178+
179+
private Mono<User> query(QueryUser query) {
180+
return gateway.requestReply(new AsyncQuery<>("query.name", query), "target.name", User.class);
123181
}
124182
//...
125183
}
126184
--------
185+
186+
=== Reactive Commons - Listening for Events, Commands and Query messages
187+
188+
==== HandlerRegistry
189+
190+
Inbound messages are listened from an event bus using `HandlerRegistry` class. The @EnableMessageListeners annotation enable you to listen messages like Events, Commands or Queries. You have to create a HandlerRegistry object, so you can register handlers for specifc messages.
191+
192+
[source,java]
193+
--------
194+
@SpringBootApplication
195+
@EnableMessageListeners
196+
public class MainApplication {
197+
...
198+
}
199+
--------
200+
201+
The HandlerRegistry implements builder patter, so each time you use some method, it will return a HanlderRegistry object. HanlderRegistry has the following methods:
202+
203+
* listenEvent: It lets listen for an event
204+
* serveQuery: It lets listen for a query
205+
* handleCommand: It lets listen for a command
206+
207+
===== HandlerRegistry - listenEvent
208+
209+
listenEvent method lets you register a handler for a specific event. It has the next signature:
210+
211+
[source,java]
212+
--------
213+
HandlerRegistry listenEvent(String eventName, EventHandler<T> fn, Class<T> eventClass)
214+
--------
215+
216+
Where the EventHandler interface signature is:
217+
218+
[source,java]
219+
--------
220+
public interface EventHandler<T> extends GenericHandler<Void, DomainEvent<T>> {
221+
}
222+
--------
223+
224+
[NOTE]
225+
The return type of the EventHandler is Void
226+
227+
So, for example, if your application want react to user.registered event, you can define a handler for that event like this:
228+
229+
[source,java]
230+
--------
231+
@Configuration
232+
public class SomeConfigurationClass {
233+
234+
@Autowired
235+
private ManageTasksUseCase someBusinessDependency;
236+
237+
@Bean
238+
public HandlerRegistry eventMessages() {
239+
return HandlerRegistry.register()
240+
.listenEvent("user.registered", event -> someBusinessDependency.functionReturningMonoVoid(event), UserRegistered.class)
241+
}
242+
}
243+
--------
244+
245+
===== HandlerRegistry - handleCommand
246+
247+
handleCommand method lets you register a handler for a specific command. It has the next signature:
248+
249+
[source,java]
250+
--------
251+
HandlerRegistry handleCommand(String commandName, CommandHandler<T> fn, Class<T> commandClass)
252+
--------
253+
254+
Where the CommandHandler interface signature is:
255+
256+
[source,java]
257+
--------
258+
public interface CommandHandler<T> extends GenericHandler<Void, Command<T>> {
259+
}
260+
--------
261+
[NOTE]
262+
The return type of the CommandHandler is Void
263+
264+
So, for example, if your application want react to user.register command, you can define a handler for that command like this:
265+
266+
[source,java]
267+
--------
268+
@Bean
269+
public HandlerRegistry commandMessages() {
270+
return HandlerRegistry.register()
271+
.handleCommand("user.register", cmd -> someBusinessDependency.handleCommand(cmd), UserRegister.class);
272+
}
273+
--------
274+
275+
===== HandlerRegistry - serveQuery
276+
277+
serveQuery method lets you register a handler for a specific query. It has the next signature:
278+
279+
[source,java]
280+
--------
281+
HandlerRegistry serveQuery(String resource, QueryHandler<T, R> handler, Class<R> queryClass)
282+
--------
283+
284+
Where the QueryHandler interface signature is:
285+
286+
[source,java]
287+
--------
288+
public interface QueryHandler<T, C> extends GenericHandler<T, C> {
289+
}
290+
--------
291+
[NOTE]
292+
The return type of the QueryHandler is a generic C
293+
294+
For example, if your application want react to user.information query, you can define a handler for that query like this:
295+
296+
[source,java]
297+
--------
298+
@Bean
299+
public HandlerRegistry queryMessages() {
300+
return HandlerRegistry.register()
301+
.serveQuery("user.information", query -> someBusinessDependency.findSomething(query), SomeQuery.class);
302+
}
303+
--------
304+
305+
TIP: Remember HandlerRegistry use builder pattern, So, you can build a chain of listener for each message:
306+
307+
[source,java]
308+
--------
309+
@Configuration
310+
public class SomeConfigurationClass {
311+
312+
@Autowired
313+
private ManageTasksUseCase someBusinessDependency;
314+
315+
@Bean
316+
public HandlerRegistry notificationEvents() {
317+
return HandlerRegistry.register()
318+
.listenNotificationEvent("some.event.name", event -> someBusinessDependency.someFunctionReturningMonoVoid(event), SomeClass.class)
319+
.listenEvent("some.event.name2", event -> someBusinessDependency.functionReturningMonoVoid(event), Some.class)
320+
.serveQuery("query.name", query -> someBusinessDependency.findSomething(query), SomeQuery.class)
321+
.handleCommand("command.name", cmd -> someBusinessDependency.handleCommand(cmd), CmdClass.class);
322+
}
323+
}
324+
--------

0 commit comments

Comments
 (0)