Overview

MicroPlode – Implementing the first Microservice

No Comments

Content

Context: Where am I here and why is it so dark :-)?
Getting started: Setting up a new project for our first Microservice implementation.
Message for you: Doing the hard things first.
Conclusion and Outlook: Some thoughts on the progress of the project and how to continue.

Context

If you are wondering what is going on here you probably missed the first blog post in this series. I could sum up things here, but I believe it makes more sense to read that first blog post to really understand the idea of this.

After doing this – and hopefully there is still interest to continue 🙂 – we are getting started right away.

Getting started

One good thing I understood from Microservices so far is that I am quite free in choosing my technology stack. Of course all Microservices that are forming the application must support the underlying communication platform and must be deployable to the target system. Here this means support for the used messaging platform and executable under Linux/Mac OS/Windows. Apart from that everything else regarding used technologies would be up to me (the team so to say :-)). This would include the programming language and the used IDE as well as the used build system. Somehow that sounds and is pretty cool. Even though some colleagues already made fun on me that I will probably do the whole thing in Perl. Of course this would be tempting, but I decided to go for Spring Boot.

And how cool is this I have to say. It is really good to every now and then stick the head out of the ongoing-project-world-window so to say and see what has happended outside in the meantime. It took me roughly 5 minutes (and this is no exaggeration) to setup the project using Spring Initializer. This way it was also really straightforward to implement a first Web Service.

Building the whole thing with Maven creates an executable JAR that can be started right away … as the first Microservice.

p2-gameservice

That is really pretty amazing. Now what I would like to have is a simple WebService to trigger some action in the whole application. Later on these WebService calls will probably be triggered by the frontend. But of course it is also a nice and easy way to start playing around with the application and potentially do some automated tests later on. The class implementing the WebService is really straightforward.

package de.codecentric.microplode.controller;

import de.codecentric.microplode.messaging.MessageSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/trigger-action")
public class TriggerActionController {

    @Autowired
    private MessageSender messageSender;

    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody String triggerAction() throws Exception{
        messageSender.sendMessage("Trigger Action");
        return "TriggerAction Called";
    }
}

One can see already here that a MessageSender class is injected and used to obviously send a message :-). More on the messaging is soon to come, but in general to follow the progress of this project also later on I am doing GIT tags with every “milestone” reached. Currently this means with every new blogpost :-).

Game Service Repository (1.0.0)
Playing Field Service Repository (1.0.0)
Computer Player Service Repository (1.0.0)
Documentation Repository (1.0.0)

It is really not a lot of code yet, but nevertheless it contains a WebService to trigger sending a message in the GameService. This message is then received in both – the PlayingFieldService and the ComputerPlayerService – microservices. The documentation-repository is intended to serve as a minimal documentation which I think is even useful if working on the project alone. But luckily a codecentric colleague of mine (hello Jonas :-)) is right now joining the project. Beside the fact that it is more fun, this way we can of course better judge the impact of using Microservices on working on an application in a team.

Message for you

As this is a playground project we are using messaging no matter if that is really 100% required or not. Probably we could survive as well using synchronous REST calls for example. But as said earlier I want to see where this whole messaging solution leads us and thus gain some insight in advantages and potential problems using messaging.

In the first post of this series I was still thinking to use Kafka as the messaging platform for this project. For me it turned out – after some further evaluation – that this is too complicated for this project or – more probably – my understanding of it is too limited. Thus I switched to RabbitMQ. This has been working like a charm from the very beginning. My proof-of-concept implementation is thereby mainly based on the following Spring tutorial: https://spring.io/guides/gs/messaging-rabbitmq/

Starting with the messaging for me is a quite natural thing to do as the motto is “doing the hard things first”. And of course getting the messaging straight is important as this is the foundation to enable the communication between the individual services. Maybe for someone who has done half a dozen projects in this setup it will no longer be a big deal, but I think currently this is not really a mainstream approach to do things yet.

Switching to the technical aspects using RabbitMQ things have become really straightforward. Installation on Windows is simply done with an installer. Only thing is that you need to install Erlang first. Afterwards the RabbitMQ server can simply be started as an executable which I found a bit more straightforward than what was needed for Kafka. Of course I cannot judge at all any other technical advantages/disadvantages of the two systems, but in ease of use RabbitMQ simply made it for me.

p2-events

The above figure is a slightly updated version of the one shown in the first blog post of this series. Not too much has changed beside the fact that the PlayerService is now the ComputerPlayerService and also REST calls and the used messaging platform are integrated into the figure. The code for sending/receiving a message can be seen from the GIT repositories linked earlier. Probably the only special thing to mention is the use of the Fanout Exchange to be able to send the same message to different queues and thus to different consumers. For sure we will also check out Topic Exchange for this in the near future, but for the time being this is a solution that seems to work good enough for our requirements.

Conclusion and Outlook

This series of blog posts is driven by two major ideas:

  1. Gaining first hand experiences with technologies used in a Microservices ecosystem.
  2. But for sure as important getting a “feeling” what it means to work on Microservices instead of a monolithic application.

The first part has been covered by using SpringBoot to create individual services and by implementing a first solution for the messaging infrastructure. The second part is gaining more momentum now that a colleague has joined the project as mentioned above.

Of course the whole application is not too complicated, but splitting up responsibilities, now that Jonas is joining the project, was really easy. Jonas is simply taking over the development of the GameService microservice. We only needed to share a bit of documentation to get this started, like how to identify fields on the board and how to identify players in messages. Furthermore at least for the time being all communication to the – or better a potential – frontend is encapsulated in that service. So Probably I will implement some hook to trigger certain actions on “my” microservices, but otherwise we are totally seperated. We are not even sharing the popular “commons” project. Our interfaces are defined by the queue names and the format of the JSON strings and I would really not mind (nor notice until I look into the code) if that GameService gets now rewritten from scratch in Python as an example.

What is the downside to this approach then? When talking about the board there will be a need to repeat the implementation for the representation of that board in different services for sure. Especially as handling the board will be one of the more complex parts of the application. But then again the complexity will differ probably between different services. The same is true for storing player information. Parts of those will be duplicated to the different services and must be kept there.

Nevertheless currently I think this duplication of data might also be a chance. How often have you ended up in a project with overly complex “domain objects” that might be hard to change and maintain in the end. The important thing is of course that there is always one service that has the final responsibility on certain data. For the board this obviously is the PlayingFieldService and for the players it is the GameService.

What next then? I say a first working version where two human players can play against each other. Of course everything without a GUI, but playable by doing the corresponding REST calls to start a new game and to make a move. The current state can then be printed out for debugging purposes anyway and basically that is all that is required (beside some minor things like calculating the explosions and detecting game-ended-situations :-)). That is a plan!

So the next blog post will hopefully show that result and will be written as some kind of dialogue between Jonas and me sharing our experiences and learnings from working in a Microservices project setup.

Comment

Your email address will not be published. Required fields are marked *