MicroPlode – A Microservices Experiment
Part I: MicroPlode – A Microservices Experiment
Part II: MicroPlode – Implementing the first Microservice
This blog post will differ quite a bit from the previous ones of this series. Now that even two codecentric colleagues have joined this experiment (hello Jonas and Bastian ) we will take the chance to simply mix up our ideas and experiences in this blog post. It is great that we are a team of three now working on this. It enables a lot of interesting ideas and discussions and at the same time is of course better “simulating” working on a Microservices project as a team.
First of all an update on our “architecture” as it has evolved again. Especially a new presentation-service microservice has been added. This is definitly the source for some interesting discussions as we decided to go for one service doing all the GUI implementation and not spreading that responsibility to the individual services.
At the end of this blog post there are the links to the tagged versions of the code representing the current snapshot of the project.
Thomas: Well, of course this cannot be compared to a real customer project in complexity of the requirements and thus the needed interfaces, but still for me it felt very easy to get Jonas and Bastian on board in the project. After a short discussion on the content of the interfaces (the different messages we are sending back and forth) there are not really a lot of things to agree on. We are working in separated (Java) projects for now.
Jonas: And now I am in. All I did was to read Thomas’ blogpost. Ok, and we gabbed about our experiences regarding microservices. Then these idea came into our minds and I took over the game service, where one doesn’t need much experience with Hexplode . It started out, that I won’t go for Python – but at least I thought about it 🙂 SpringBoot was already set up and highly appreciating, so I stuck with it. But there was one more thing, we had to agree on – the underlying messaging infrastructure. And I appreciated RabbitMQ, too – although not really fancy, but working for our needs.
One of my first impressions: If you use the same language for 2 or more microservices and u have a common interface-format (which you simply need), than maybe copying Pojos for that would be ok 🙂 I know, sharing domain objects is evil. But we don’t share anything else in the future, I swear!
Second impression: Starting all microservices on your local machine will make you fan of a Terminal with tabs. Without that you will get in trouble trying to stay on top of things.
Third one: Oh my… We need a messaging infrastructure! It’s obvious, but funnily enough I forgot. Well that reminds me of something… What was it called…?!
Thomas: The discussions about the frontend/UI are really interesting as they go back and forth. There is this kind of paradigm that a microservice contains everything it needs. This would include UI elements. But what if there are UI elements that are shared by two microservices? Then it cannot be really included into one of the services. Maybe this might indicate that your services are not sliced properly, but somehow I doubt that and otherwise things would probably become more monolithic again.
We did not make this an easy decision for us, but for the time being we introduced an additional service for this, namely the presentation-service. That one will one the one hand side communicate to the other services via messaging, but will also contain the complete UI. What I like about this is that the kind of technology used to communicate between frontend and backend is encapsulated this way in this service.
Bastian: Yes, the discussion that each microservice should contain its own UI is probably an important one and we cheated on that a bit for now. On the other hand the current presentation service nicely demonstrates one advantage of the microservice approach – the ability to quickly add services in different programming languages, using the most suitable technological platform for the problem that a particular service is trying to solve.
We decided early on that the frontend would be done in Elm (for no particular reason except that Elm is my current preference for frontend work). Also, from the flow of the game and the way we modeled the interaction between the game frontend and the services it was pretty obvious that a communication based on server push would make a lot of sense. So we needed to put websockets into the mix. Unfortunately, Elm has currently no direct support for websockets and we didn’t feel like rolling our own elm-websocket module here. But, there is a Socket.io package for Elm, hooray. In case you are unaware of the subtle differences, Socket.io is built on top of Node.js and the raw websockets protocol to do the heavy lifting and offer a more convenient API. But, as said, it’s a Node.js thing, not Java and all the other existing microservices are implemented in Java and SpringBoot.
The point is, with microservices this is not a problem at all. We can build the presentation service with Node.js and Socket.io just fine and let it talk to the other services via AMQP. Problem solved \\o/
Jonas: Before focusing on AMQP as the main communication channel during the game, we also couldn’t help but bikeshed quite a bit about “how to build real REST-Services” … err “Resources” (sorry for the side blow, Bastian 😉 ). I guess you just need to have this particular discussion at least once in every project. In our game service we started with pretty much the knowledge of one of the nice spring.io starter guides . But as soon as we left the hello-world-scope, things became confusing. But there are some nice Annotations for the rescue, according to the docs. Especially with the @RabbitListener one get things done quite fast:
@RabbitListener(queues="microplode-queue")
public void handleMessage(@Payload Event event) {
System.out.println("Event received:" + event.getType().getText());
}
To get your methods bound to the actual queues, you have to define a @Configuration-annotated class, where you add @EnableRabbit and derive from the RabbitListenerConfigurer-Interface. In the overridden configureRabbitListeners()-method you simply declare a MessageHandlerMethodFactory (for JSON-events with an optional MappingJackson2MessageConverter()) and add a Bean SimpleRabbitListenerContainerFactory – and you’re done. You can see this in our github-repository.
But we still don’t have a real Topic, where some services subscribe to and they get notified, when there’s an event waiting for them. So let’s improve this further!
Thomas: Yeah It twitches 🙂
Some final thoughs for today: I was about to give up on the messaging as it felt somehow too complicated and hard to test, but I am glad especially Bastian was persuading me to stick to it. And if only to try things out. And as can be seen above it worked out :-). Anyway for testing purposes I implemented some REST endpoints for testing purposes, which is also used in the above vides:
http://localhost:8090/boardservice/initialize-game
http://localhost:8090/boardservice/make-move/5/3/1
Calling those is then triggering a board-change-event.
Could write on forever as it gets more and more interesting, but we need to spare some things for a next blog post :-).
Here is the current snapshot of the project in case you would like to take a closer look to the sources:
Presentation Service Repository (1.0.0) (new)
Game Service Repository (1.1.0)
Board Service Repository (1.1.0)
Computer Player Service Repository (1.1.0)
Documentation Repository (1.1.0)
More articles
fromThomas Jaspers
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Thomas Jaspers
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.