Skip to content

Latest commit

 

History

History
 
 

drestaurant-microservices-rest-2

Microservices / REST / AxonServer

:octocat: /drestaurant-apps/drestaurant-monolith-rest-2 :octocat:

This is a thin layer which coordinates the application activity. It does not contain business logic. It does not hold the state of the business objects

We designed and structured our loosely coupled components in a modular way, and that enable us to choose different deployment strategy and take first step towards Microservices architectural style.

Each microservice:

  • has its own bounded context,
  • has shared event(sourcing) storage (AxonServer)
  • and we route and distribute messages (events, commands, queries) between them via AxonServer

This a second version (2.2) of the REST Microservices application in which we use AxonServer as an infrastructural component.

AxonServer & event messages & command messages & query messages

Both AxonFramework and AxonServer form an Axon platform.

The key characteristics of AxonServer are:

  • Dedicated infrastructure for exchanging three types of messages (commands, events, queries) in a message-driven micro-services environment
  • Purpose-built database system optimized for the storage of event data of the type that is generated by applications that use the event sourcing architecture pattern
  • Built-in knowledge on CQRS message patterns
  • Easy-to-use and easy-to-manage

AxonServer connector is configured by default (included in axon-spring-boot-starter) :

<dependency>
    <groupId>org.axonframework</groupId>
    <artifactId>axon-spring-boot-starter</artifactId>
    <version>${axon.version}</version>
</dependency>

Alternatively, you can exclude AxonServer connector and fallback to JPA event store and storage in general. In that case you have to choose (and configure, and operate) Spring Cloud to distribute commands, and Kafka or RabbitMQ to distribute events.

<dependency>
    <groupId>org.axonframework</groupId>
    <artifactId>axon-spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.axonframework</groupId>
            <artifactId>axon-server-connector</artifactId>
        </exclusion>
    </exclusions>
</dependency>

We did this already in the first version of 'REST Microservices application' as a proof that you can benefit from AxonFramework programming model only (without AxonServer as an infrastructural component). first version is using:

  • RabbitMQ to distribute events between microservices
  • Spring Cloud discovery and registry service (Eureka) to distribute commands between microservices
  • no out of the box option to distribute queries -> each microservice has command and query side component included -> there is no independent query microservice -> you can not scale good

AxonFramework programing model is recognizing three categories of messages at the moment:

  • commands
  • events
  • queries

and they require different mechanisms of routing and distributing. AxonServer is built with this in mind, and you should consider it as an important tactical asset in you architecture. This will enable you to focus on your domain model and strategic design.

AxonFramework and AxonServer are open source. Axon Server Enterprise is targeted towards mission-critical, medium to large scale production deployments of Axon.

Restaurant management

Read all restaurants
curl http://localhost:8085/restaurants
Create new restaurant
curl -i -X POST --header 'Content-Type: application/json' --header 'Accept: */*' -d '{
"menuItems": [
 {
   "id": "id1",
   "name": "name1",
   "price": 100
 }
],
"name": "Fancy"
}' 'http://localhost:8084/restaurants'
Mark restaurant order as prepared
curl -i -X PUT --header 'Content-Type: application/json' --header 'Accept: */*' 'http://localhost:8084/restaurants/RESTAURANT_ID/orders/RESTAURANT_ORDER_ID/markprepared'

Customer management

Read all customers
curl http://localhost:8085/customers
Create/Register new Customer
curl -i -X POST --header 'Content-Type: application/json' --header 'Accept: */*' -d '{
"firstName": "Ivan",
"lastName": "Dugalic",
"orderLimit": 1000
}' 'http://localhost:8082/customers'

Courier management

Read all couriers
curl http://localhost:8085/couriers
Create/Hire new Courier
curl -i -X POST --header 'Content-Type: application/json' --header 'Accept: */*' -d '{
"firstName": "John",
"lastName": "Doe",
"maxNumberOfActiveOrders": 20
}' 'http://localhost:8081/couriers'
Courier takes/claims the Order that is ready for delivery (prepared)
curl -i -X PUT --header 'Content-Type: application/json' --header 'Accept: */*' 'http://localhost:8081/couriers/COURIER_ID/orders/COURIER_ORDER_ID/assign'
Courier marks the order as delivered
curl -i -X PUT --header 'Content-Type: application/json' --header 'Accept: */*' 'http://localhost:8081/couriers/COURIER_ID/orders/COURIER_ORDER_ID/markdelivered'

Order management

Read all orders
 curl http://localhost:8085/orders
Create/Place the Order
curl -i -X POST --header 'Content-Type: application/json' --header 'Accept: */*' -d '{
"customerId": "CUSTOMER_ID",
"orderItems": [
 {
   "id": "id1",
   "name": "name1",
   "price": 100,
   "quantity": 0
 }
],
"restaurantId": "RESTAURANT_ID"
}' 'http://localhost:8083/orders'

Note: Replace CUSTOMER_ID and RESTAURANT_ID with concrete values.

Development

This project is driven using Maven.

Clone

$ git clone https://github.com/idugalic/digital-restaurant

Build

$ cd digital-restaurant
$ mvn clean install

Run microservices

NOTE: AxonServer is required.

$ cd digital-restaurant/drestaurant-apps/drestaurant-microservices-rest/drestaurant-microservices-rest-2-query
$ mvn spring-boot:run
$ cd digital-restaurant/drestaurant-apps/drestaurant-microservices-rest/drestaurant-microservices-rest-2-command-courier
$ mvn spring-boot:run
$ cd digital-restaurant/drestaurant-apps/drestaurant-microservices-rest/drestaurant-microservices-rest-2-command-customer
$ mvn spring-boot:run
$ cd digital-restaurant/drestaurant-apps/drestaurant-microservices-rest/drestaurant-microservices-rest-2-command-restaurant
$ mvn spring-boot:run
$ cd digital-restaurant/drestaurant-apps/drestaurant-microservices-rest/drestaurant-microservices-rest-2-command-order
$ mvn spring-boot:run

Infrastructure and Platform (As A Service)