Trifork Blog

Posts Tagged ‘Axon Framework’

Exposing asynchronous communication through a synchronous REST API with Spring 5

April 13th, 2018 by
(https://blog.trifork.com/2018/04/13/exposing-asynchronous-communication-through-a-synchronous-rest-api-with-spring-5/)

Author – Erwin de Gier

On my current project, we opted not to use REST for the communication between our services. Instead we make use of AxonIQ’s AxonHub, which acts as a specialized message broker. Messages can be of three types:

  • Command – You want to change something
  • Event – You want to inform others of something that happened
  • Query – You want to know something

The communication is asynchronous and we also have to deal with eventual consistency. If we would create an order by sending a CreateOrderCommand, this order would result in various events which update the state of the Order. We then need to send a query, of which we also receive the result asynchronous.

Our web and mobile frontend communicate with a microservices backend through a REST API. When the user creates an order (clicks the ‘buy’ button), they expect a result immediately. For both frontends, an API which models this user experience closely makes the most sense. This means that we want a more synchronous API, where we send a ‘create order’ request and immediately receive a response.

We implemented this using a small REST facade which translates our asynchronous communication in the backend to the synchronous communication for the frontend. This is a good use case for Spring 5’s reactive Webflux and Project Reactor. Using Project Reactor’s reactive API makes it possible to combine multiple asynchronous calls and operate on their result. Webflux handles the conversion of the reactive types (Mono, Flux) to REST responses. It optimizes the use of threads; by writing non-blocking code, we can reuse threads between asynchronous calls for handling other requests.

Diagram 1 gives us an overview of this approach.

Diagram 1

 

Implementation

Let’s have a more detailed look at the code for the create order example. Listing 1 shows the (slightly) simplified implementation of our REST controller method.

@PostMapping
public Mono<ResponseEntity<OrderResponse>> createOrder(CreateOrderRequest request) 
{
 CreateOrderCommand command = CreateOrderCommand.fromRequest(request); //1

 return this.commandGateway.send(command) //2
  .flatMap(id -> queryGateway.send(new FindOrderSummaryQuery(id))) //3
  .retryWhen(errors -> errors.delayElements(Duration.of(100, MILLIS)) //4
  .take(10)).concatWith(Mono.error(new RuntimeException())).next() //5
  .onErrorReturn(new OrderResponse(orderID, OrderStatus.CREATED)) //6
  .map(orderResponse -> ResponseEntity.ok().body(orderResponse)); //7
}

Listing 1

We first create a command out of the REST request (line 1). A command is a message with the specific intent to change something in our domain. In this specific case, we want to create a new order.

After creating the command, the two asynchronous calls we make are:

Mono<String> id = this.commandGateway.send(command);

and:

Mono<OrderResponse> orderResponse = queryGateway.send(new FindOrderSummaryQuery(id));

Both calls return a single value by using a Mono. A Mono is a reactive type, comparable to the Java’s CompletableFuture. It has zero or one element and can represent an error. As with all reactive types, the value (or error) is delivered over time.

The second call takes the result of the first call as its input. We need the returned id of the command to query for the order. We use the flatMap operator to achieve this (line 3). The flatMap takes the asynchronous result of call 1 and passes this as a parameter to the lambda of call 2. The callback version can be seen in Listing 2: notice the nested lambda, which makes the code complex and less readable.

this.commandGateway.send(command, id -> {
  queryGateway.send(new FindOrderSummaryQuery(id));
});

Listing 2

There is a delay between sending the command and being able to query the result. When the created order cannot be found (e.g. it isn’t create yet or something has gone wrong), an exception is thrown. In this chain, this is represented as a Mono.error(throwable). We use the retryWhen method to retry the query (line 4). We do this 10 times with a delay of 100 ms. When we still don’t get a result, we throw an error (line 5). We don’t expose the error to the client, but pass an OrderResponse with the id and status CREATED (line 6). The client can then query the status of the order later by using this id. This is a form of graceful degradation.

Finally we map the order response from the query to a response entity which can be returned by Spring. Spring actually subscribes to this whole chain and sends out the REST response for us.

Conclusion

Spring 5 and Project Reactor allow us to handle asynchronous communication with concise and readable code. We can do retries, error handling and the combination of multiple asynchronous calls in just a few lines.
The integration of Webflux with Project Reactor allows the use of reactive paradigms in a REST controller. Webflux uses an asynchronous approach. While we wait for a backend query to return, we don’t block the main thread. this allows it to be used for other requests.
Our specific use case is a good example of one of the applications of Spring 5 Webflux and Project Reactor.

Using Axon with PostgreSQL without TOAST

October 9th, 2017 by
(https://blog.trifork.com/2017/10/09/axon-postgresql-without-toast/)

The client I work for at this time is leveraging Axon 3. The events are stored in a PostgreSQL database. PostgreSQL uses a thing called TOAST (The Oversized-Attribute Storage Technique) to store large values.

From the PostgreSQL documentation:

“PostgreSQL uses a fixed page size (commonly 8 kB), and does not allow tuples to span multiple pages. Therefore, it is not possible to store very large field values directly. To overcome this limitation, large field values are compressed and/or broken up into multiple physical rows”

As it happens, in our setup using JPA (Hibernate) to store events, the DomainEventEntry entity has a @Lob annotation on the payload and the metaData fields (via extension of the AbstractEventEntry class):

For PostgreSQL this will result in events that are not easily readable:

SELECT payload FROM domainevententry;

| payload |
| 24153   |

The data type of the payload column of the domainevententry table is OID.

The PostgreSQL JDBC driver obviously knows how to deal with this. The real content is deTOASTed lazily. Using PL/pgSQL it is possible to store a value in a file. But this needs to be done value by value. But when you are debugging your application and want a quick look at the events of your application, this is not a fun route to take.

So we wanted to change the data type in our database to something more human readable. BYTEA for example. Able to store store large values in, yet still readable. As it turned out, a couple changes are needed to get it working.

It took me a while to get all the pieces I needed. Although the solution I present here works for us, perhaps this could not be the most elegant of even the best solution for everyone.
Read the rest of this entry »

Axon from the trenches: how to keep your code compatible with legacy events and Sagas

June 8th, 2015 by
(https://blog.trifork.com/2015/06/08/axon-from-the-trenches-how-to-keep-your-code-compatible-with-legacy-events-and-sagas/)

Imagine you’re using Axon to run an event sourcing application. Your production event store might contain millions of events, created in various versions of the application. Wouldn’t it be nice to know for sure that the latest version of your application plays nicely with all your production events and Sagas, including those from previous versions? Well, you can check for that, and it is fairly easy. Read the rest of this entry »

CQRS as a Junior Developer

April 21st, 2015 by
(https://blog.trifork.com/2015/04/21/cqrs-as-a-junior-developer/)

Fresh from university, searching for a development job, having one within two weeks. And at an interesting company at that. That is what happened to me about a year ago. So, you could (and probably should) call me a junior developer. After a month of trainings and new experiences I was put on my first big project. Together with a senior colleague we were assigned to build the new roadside assistance application at the ANWB. The app was planned to work with Axon at the core and through this I came in touch with CQRS

Since I didn’t know squat about the ‘Command-Query Responsibility Segregation’ concept and soon had to work with it, I dove into a multitude of sites, blogs and wikis about the topic for self-study. That it separates the responsibility of commands and queries is quite obvious from the definition itself. And that this leads to scalability options since the command or the query side can be optimized to the system, made sense. Also, that it simplifies the creation of the domain model since there can be a focus on either the command or query side was quite clear through the information I read.

Read the rest of this entry »

New features in Axon Framework 2.1

February 13th, 2014 by
(https://blog.trifork.com/2014/02/13/new-in-axon-2-1/)

Recently, Axon Framework 2.1 has been released. It comes packed with improvements and some exciting new features. In this post, I’ll briefly iterate of what’s new in this version.

Furthermore, we have also scheduled a few workshops and trainings.

Read the rest of this entry »

GOTO Academy – Training & Courses

January 15th, 2014 by
(https://blog.trifork.com/2014/01/15/goto-academy-training-courses/)
The GOTO Academy is organising regular training sessions around professional software development and architecture.
We are currently running a New Year promo: 20% discount on the iOS trainings.
Take advantage of it! Use the voucher code: TRIFORK2014 to book your seat before end of January 2014. Register here, select the training (iOS beginner or advanced) and type the voucher code in the comment section.

Latest news from Trifork Amsterdam

June 17th, 2013 by
(https://blog.trifork.com/2013/06/17/latest-news-from-trifork-amsterdam/)

Just 1 day to go until #3 GOTO Amsterdam

The team behind GOTO Amsterdam are raring to go and this time it’s already set to be the best year to date. Not only in terms of an impressive speaker line up and record number of delegates, but also the sponsors this year have pulled the stops out.

es logoWe at Trifork Amsterdam & Elasticsearch will be partners in crime this year and have a host of FREE fantastic giveaways including trainings seats & conference tickets to be redeemed across the globe. There’s also a chance to hear about the customers using Elasticsearch and get insights as to how best to implement Elasticsearch in a production environment. So if you’re at the event come and visit us (hint: if want to locate us, follow the scent of delicious warm waffles!).

Read the rest of this entry »

AFAS’ CIO Rolf de Jong hosts Panel Discussions at Axon Seminar

February 12th, 2013 by
(https://blog.trifork.com/2013/02/12/afas-cio-rolf-de-jong-hosts-panel-discussions-at-axon-seminar/)

axon2_banner

On February 28th 2013, Trifork will organize the Axon 2 launch seminar. During this seminar, visitors will be introduced to CQRS and Axon Framework, of which version 2 was released just a few weeks ago. The seminar will be an afternoon packed of technical insight, case studies and panel discussions, whereby we look forward to a number of informative and interactive sessions. Rolf de Jong, CIO of AFAS ERP Software, has accepted our invitation to host the panel discussions where a team of experts will share their thoughts on CQRS, Axon Framework and software development in general.  Read the rest of this entry »

Axon Framework 2.0 Released!

January 22nd, 2013 by
(https://blog.trifork.com/2013/01/22/axon-framework-2-0-released/)

After laying the ground work for this release about a year ago, we now proudly announce the next major release of Axon Framework! The 2.0 release is a big step forward compared to the previous version, as it contains a thorough restructuring of components, making it even easier to build scalable and extensible applications.
Read the rest of this entry »

Axon Framework 2.0-rc1 released

November 30th, 2012 by
(https://blog.trifork.com/2012/11/30/axon-rc1-released/)

Axon 2 has hit an important milestone today, as we have published the first Release Candidate. This release marks a major milestone towards the final 2.0 release, expected early January. All features on the roadmap have been implemented in this release. The coming weeks, these features will be refined and fine-tuned for optimal performance and reliability to ensure Axon 2.0 helps meet the demands applications face today.

Read the rest of this entry »