Micro service based architecture

Introduction

This post is part of a series that describes the implementation of a fully automated continuous deployment pipeline. For an overview and a table of content please refer to this post.

In this post I want to discuss what a micro service is and what it is not. I also want to list some reasons why you want to use micro services and why you might want to avoid them. Finally I want to give a brief overview of the implications when using a micro service based architecture.

Micro service what?

The word micro is misleading many developers that first encounter this pattern. It should not be taken literally. We should rather thing of a micro service (MS) being something smallish.

A MS most often is a set of coherent functionality that logically belongs together. If you are familiar with DDD you can think of it as the implementation of bound context. But this is not the only way how we can define a MS. Other reasons are possible, why you would want to wrap a piece of functionality into a MS. Some are

  • Frequency of change: Part of the application needs to be changed frequently whilst the remaining part is rather stable and changes rarely.
  • Infrastructure: Part of the application has very specific requirements on the infrastructure it runs on. This can be e.g. an extreme need for RAM or disk I/O or network throughput. The remaining of the application does not have this very specific requirement.
  • Scalability: Part of the application needs to be very scalable compared to the remainder of the application
  • Security: Some elements of the application have very high security constraints.
  • Tool set: Parts of the application would benefit from being implemented in a specialized language, e.g. a functional language like F# or Clojure.
  • Platform: Sometimes we want to run parts of the application on another platform like a different flavor of Windows or Linux.
  • etc.

 Characteristics of a micro service

Once we have identified the functionality we want to implement as a micro service we need to make sure our micro service has the following characteristics

  • The micro service acts like a black box to the outside world. It has well defined external facing interfaces.
  • A micro service should be replaceable by another implementation of the same functionality without side effects. Of course the new implementation needs to implement the same contracts as the previous implementation.
  • The contracts with the outside world are well defined and should change infrequently if ever possible.
  • Contracts with the outside world need to be versioned to make a micro service backwards compatible with older consumers. New consumers can use the newer version of the interface and/or contract.
  • A micro service should have its own code repository e.g. on GitHub or any other source code version control software you’re using. Note: Some people do not like this but then at least the micro service should have its own sub-reporsitory inside the main repository.
  • Each micro service is its own unit of deployment. Each MS evolves independently from the other parts of the application and can be deployed at any time without a need to also deploy newer versions of other micro services.

Since by definition a micro service is smallish then it follows that the amount of code necessary to implement a micro service is limited. As a consequence we can often avoid to implement certain patterns that are used in a monolith to tame the complexity of an ever growing monolith. Such patterns can be the use of an IoC container or the use of a ORM like NHibernate or Entity Framework.

Interfaces of a micro service

The functionality of a micro service needs to be accessible from the outside world. For this reason any micro service implements a set of well defined interfaces. Often these interfaces are implemented as RESTful APIs. But this is by far not the only option at hand. Other possible types of interfaces are message queue handler, tcp/ip or udp based interfaces, etc. Since in a typical application most of the micro services are not exposed to the public we are free to use whatever protocol or technology suits best our needs. Thus don’t artificially restrict yourself to the use of only RESTful APIs. It is much more important that the interface of a micro service remains stable over time and is versioned.

Samples of micro services

To not just talk abstractly about micro services lets give a few samples of what would be good candidates for a micro service

  • Product catalog: This service provides functionality to maintain the inventory of a shop such as adding, modifying and discontinuing products.
  • Shipping: Once a customer has placed an order this service handles the shipping of the products to the customer.
  • Document generator: To comply with certain regulations and laws documents have to be generated during a business transaction and be presented to the customer. A typical sample document is the adverse action notification whenever the a hard inquiry for the credit score of a customer has been made. This service generates documents based on templates and fills in dynamic data.
  • Email service: this service is responsible to generate emails from templates using a technology like mail merge and send the finished emails using a SMTP server to the recipients. Emails can be triggered by events or be sent based on a predefined schedule.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 25 years as a consultant, software architect, trainer, and mentor mainly on the .NET platform. He is currently working as senior software architect at Alien Vault in Austin, Texas. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in architecture, introduction, Micro services, patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • calum bett

    Excellent post as always! Looking forward to the rest of this series.

  • Harry McIntyre

    I think another key feature of a microservice is data ownership. A microservice should have exclusive write control over data within it’s domain, and expose that data to other services only through versioned mechanisms. It is impossible to independently deploy two applications which are modifying the same underlying schema.

    It is frequently suggested that this is implemented using separate databases and all data is shared over HTTP APIs, which I think causes people to baulk at the thought of breaking up a monolith which is tied to a complex database with SQL commands. A step on the way for a system like that is to have a db-schema-per-microservice with version controlled readonly views accessible to other services/schemas.

    • gabrielschenker

      Good point! Thanks for contributing.

  • beton

    Very nice and clean intro.
    Waiting for more :)

  • Peter

    Hi, great article, thanks! I’m struggling with the concept of contracts between microservices. When using rest for example a contract can be quite easily made using tools like swagger. But when microservices are message driven, especially in a pub/sub way how can contracts be described?

    My approach was to create a separate library (“nugettable”) containing the events that microservices can subscribe to. This library can be shared by different microservices. However shouldn’t events be part of the domain (ddd) and if so, how can the events be exposed as contracts?

    Any thoughts? Cheers!

    Peter

    • gabrielschenker

      Public events are contacts!

      • Peter

        :) understood! But what is the best way to expose them in a e.g. Swagger-like manner?