Importance of initial decicions

Before you start

You have joined a new team, or you are starting a new project with the one you have been working with for years. My demands are more collected – we are agile after all. Stories in JIRA are pre-written, so we open the IDE and run containers with the only correct stack:

  • Java 11 – because it is already installed, we always use it with the rest
  • Spring boot of course
  • Postgresql – because it is the best database and we always use it.

So we start to create the first microservice because there must be microservices – everyone does it and it’s a shame to do it differently.

What are we really doing?

Close for a moment IDE, and turn off the containers. Now is the time to regroup forces. I assume that at this stage you have functional requirements, and maybe even some frontend design. 

Now is the time for an additional round of questions:

  • Will we be able to define the domain elements and more or less the relationships between them?
    Yes?! Great, let’s do it!
    Depending on the experience of the team, your work style, and the amount of information you have, you should do it more or less accurately.
    Now, try to do this enough to answer the next questions.
  • How complex/extensive is its domain? Do its individual elements make sense as separate entities?
  • Are the relationships between the elements linear or do they form a dense mesh?
    Think about sample requests to the application and draw a map of what it touches triggers.
  • What will the data model look like? Will it be a group of peer entities, or will it be mainly one, and the rest complement it?

And some technical questions

  • What will be the traffic?
  • Much smaller requests or maybe fewer, but complex?
  • Where are we going to run it? Cloud, bare metal in the data center, old laptop under the desk?
  • Are HA and scalability crucial for this project?
  • How much time do we have until the first release before someone gets impatient?

Here we go

For the purposes of this article, I will use an example in which I assume that your team’s skills are centered around the Java ecosystem, but it doesn’t really matter. Go ahead and replace Java with any tool close to your heart.

I run the IDE and start the first microservice, right?

Not really – it doesn’t have to be microservices, forget that the monolith is out of fasion and it will be a shame. Your job now is to make decisions like an engineer, not an unstable teenager!

Microservices, monolith, or …

The first and usually the saddest question – how much time do we have? And possibly an auxiliary question – how much experience do we have with micro-services as a team? How many projects based on this architecture have we managed to deliver successfully?

If the time is short and your team is not super experienced in this topic, microservices will put additional pressure. 

But microservices are the best! What can go wrong?

  • Depending on the technology, it may take more or less time to start a new microservice, but it is always an additional cost. Also, think about creating repositories, CI configuration, infrastructure, and maintenance.
  • Communication between microservices is not easy. You will need to write contracts and keep them in sync for every possible pair. Regardless of the communication methods you choose, you will have to take care of network errors and latency (be aware of the physical aspects of the system! Nothing happens immediately, even RAM has some latency!)
  • Transactions wider than one microservice are a headache.
  • Sooner or later, you will need to reconcile.

So when are microservices?

  • First of all, when you have time for it,
  • When your domain or data model can be divided in a clear and relatively unambiguous way – you are able to name each microservice in two words
  • Domain elements are relatively loosely connected – do you remember the transactions?
  • It will make sense to scale particular microservices in different ways.
  • You will be able to build, monitor, and maintain the infrastructure for your solution.
  • The product will pay for its infrastructure – microservices will certainly need more resources at the start than the corresponding monolith

Something in between?

A mixture of microservices and a monolith may turn out to be a good solution when we do not have much time for the first implementation, or at the moment we do not have enough experience with microservices, but still, the architecture may turn out to be more beneficial in our case. This will allow you to rewrite only part of the solution in the this direction in the future, but to make it possible, we must remember to separate the data from the beginning. 

What is the best candidate for isolating small applications to start with?

Usually good to start with things that are well-known, and can be easily separated:

  • authentication provider – if we intend to use something like OAuth2 (based on tokens containing basic user data) this should be element quite easy to separate, it is also worth considering ready-made Keycloak solutions
  • Background processes, workers – if your system has background processing elements, it will probably be a good candidate – a simple example is image scaling or video transcoding
  • external service adapters – such as sending e-mails and SMS 

We have architecture, what to do next?

We assume that we chose one of the above options (or came up with something completely new). The next step should be to choose a technology stack. 

When it comes to choosing your main programming language, it is usually dictated by the skills of your team. If most of you have been working mainly in Java for years, probably no one will want to start a new PHP project – which is perfectly understandable. Nevertheless, many frameworks and micro-frameworks are usually available within one language.

Think about the benefits each of them can bring. You should consider things such as:

  • maturity of the solution – can we afford cutting edge, or are we looking for proven, although not so modern solutions, 
  • or one of the frameworks will fit better than the other – some of the solutions are targeted at specific data processing methods – it does not have to be a leading framework in a given technology
  • community and ecosystem – are there ready-made compone with technologies or suppliers that you will work with? Is there any chance of getting outside help?
  • technical parameters – performance, amount of memory needed, speed of start, ease of maintenance of environments – especially if you have chosen micro services, micro frameworks may be a better solution, with horizontal scaling, the speed of application launch may be an asset, the amount of memory needed may affect the costs of the environments … 
  • skills and flexibility of the team – people with good experience and passion for what they do should have no problem with changing the framework, provided that it does not differ much from the one they have used so far. The team should always discuss these types of decisions and be comfortable with them.
  • nothing prevents you from using multiple solutions if you agree that it makes sense and you feel confident with them!

Database

In most projects, this will be a key element.

In this case, you should rethink your data structures and consider whether they are relational in nature and what types of operations you will mainly perform on them. 

It is worth considering:

  • in the case of general models, whether we are dealing with relations or documents,
  • what types of operations will prevail – writing, reading, aggregation, relationships between data
  • the expected size of the data set
  • if advanced transactionality will be needed
  • solution with many types of databases – eg Postgres as the main data source and ElasticSearch with flattened relations for fast aggregations and reads
  • available tools and ecosystem 

Summary

As a software engineer, you are responsible for choosing your tools from the very first day of the project. You shouldn’t be hyped about some solutions. 

Adopt good criteria, conduct reliable research and, if possible, make a proof of concept in cases where you are not sure about something. Don’t be afraid of mixing technology, but don’t go overboard. 

Asking a few good questions at this stage can be either success or failure.

And one more important thing: don’t guess – experiment and measure!

Grzegorz Golowicz

Software Developer