Ukieweb

Diary

I write here what I learn

Understanding Microservice Architecture With Application Samples

Understanding Microservice Architecture With Application Samples

Two years ago, I wrote my yet most popular blog on microservices vs monolith The aim of the blog was to introduce my readers to the advantages of microservice architecture and how that compares to a monolith architecture. While there has been a lot of growth in adoption of microservices recently, there is still big knowledge gaps on how to design your architecture, decoupling already existing monolith application, deploying and monitoring of applications among others.

In this blog, I will guide you through some of the considerations you need to make before shifting to microservice architecture using some simple application that I developed using Nodejs and MongoDB.

The code is available on my Github repositorywhich you can clone follow through the blog and even modify to your liking.

There are three microservices and each has its own collection (database) and can operate independently. The microservices are based on subdomains around the concept on an e commerce platform.

  1. Users microservice: Creates users and manages authentication
  2. Products microservice: Creates products and manages product
  3. Orders microservice: Manages the orders and interacts with the users and products collections to retrieve data. This includes self authentication for the users instead of making an extra API call to users microservice to check if a JWT token is correct.

Running the applications

Download/ clone the code from GitHub git clone https://github.com/wbenmurimi/microservices.git

Manually

Update the database connection by updating the variable DATABASE_URL on all the .env files in the app folders. You can use locally hosted mongodb or configure a free mongo atlas cluster for testing.

Install the node_modules in each of the applications by running npm install

Run the server nodemon serve

Interact with the api via postman/equivalent API testing tool

Docker

With this approach ensure that you have docker installed. Update the database connection by updating the variable DATABASE_URL on all the .env files in the app folders. You can use locally hosted mongodb or configure a free mongo atlas cluster for testing.

Create docker images for each microservice. Note the [.] at the end. It means create the container from the content in the current directory. Otherwise you can also provide relative or absolute path to the project folder.


    docker build --no-cache --rm --tag users:v_1 .

    docker build --no-cache --rm --tag products:v_1 .

    docker build --no-cache --rm --tag orders:v_1.

Run the docker images. Note that the port numbers here are the ones that you have exposed in the Dockerfile. If you change either make sure they are the same including on the API endpoint


    docker run --rm -d -p 3000:3000 users:v_1

    docker run --rm -d -p 3001:3001 products:v_1

    docker run --rm -d -p 3002:3002 orders:v_1

Interact with the API via postman/equivalent API testing tool A couple of docker commands you can use to interact with docker containers are;

List running containers docker ps -a

Show the logs of the running container docker logs [container_id]

Stop a running container docker stop  [container_id]`` ` Start a containerdocker start [container_id```

API ENDPOINTS

GET http://localhost:3000/api/users/ Get all the users

POST http://localhost:3000/api/users/register Register a user


    {
    "name": "My User",

    "email": "[email protected]",

    "password": "myuser"
    }


POST _http://localhost:3000/api/users/login _Login a user



    {
    "email": "[email protected]",

    "password": "myuser"
    }


GET http://localhost:3001/api/products/ Get all products

POST http://localhost:3001/api/products/ Create a new product



    {

    "name": "Bread",

    "cost": "1,200"
    }

GET http://localhost:3001/api/products/{id} Get a product with a given id

Product id

GET http://localhost:3002/api/orders Get all orders

Bearer JWT token

POST http://localhost:3002/api/orders Create an new order



    {

    "product": "5e7dee2e495a5c42a3460656"

    }

    Bearer JWT token

Interact with the API as documented above and do not forget to set the correct headers [Content-Type and Accept headers should be application/json for all API calls]. Start by creating a user and then login.

Take note of the JWT token returned as shown in the screenshot below. Note that the token is only valid for one day after generation. For further API calls on the order microservice you will need to generate another token.

Microservices user authentication

Create products using the API. When you list the products, take note of one product ID that you can use to create an order.

To interact with the orders microcervice, you will need to use the JWT token returned when you authenticate to the users microservice as shown in the screenshot below. 

JWT authentication token

How To Convert A Monolith to Microservice

There are a dozen approaches that you can use to change your monolith application to a microservice. Below are some approaches that I recommend.

  1. Separate Backend and Frontend: If the frontend is still part of your application, separate them into different services. This means the backend will expose APIs that will be consumed by the frontend. At this stage, you should not focus on re-writing your application just utilize existing code base and keep it simple. Some of the frameworks you can consider for the frontend include angularjs, reactjs and vuejs.

  2. Stop making the monolith bigger: Most often extending and managing monoliths become a complex task the bigger it gets especially when adding new features. This approach means that when you are implementing new functionality you should not add more code to the monolith. Instead, the idea is to put that new code in a standalone microservice. This new microservice could function by making API calls to the mother monolith application or accessing monolith’s DB directly. This is a good step towards later decoupling the monolith as described below.

  3. Decouple the Monolith: This approach involves picking modules from the monolith and developing one after the other while still maintaining and using the monolith code. One of the common pitfalls is attempting to re-write everything from scratch. With a new architecture and a steep learning curve, it is always a good idea to avoid this move especially for production applications. Here are a couple of things to guide you on which module you should start with;

    • Modules that change frequently
    • Modules that require different resources
    • Modules that are easy to rebuild and not mission critical

Microservice Transition Success Tips

Here are some tips you should follow to ensure a successful transition from a monolith to a mmicroservice architecture.

  1. I’m always an advocate of “lazy decoupling” meaning that even though the end goal is to have independent and highly manageable services, the more services you end up with the more difficult it is to manage and even debug when things aren’t working fine. Reducing the number of services also means you will be making fewer API calls between the services which will improve the performance of the applications.

  2. While one of the benefits of microservices is being able to write them in different programming languages, do not go that route at the beginning. Having one stack for your services improves interoperability, is easier to manage and update and makes it easier to re-use components hence quick development.

  3. Services must be cohesive. A service should implement a small set of strongly related functions. This builds on the principle that things that change together should be packaged together to ensure that each change affect only one service.

Reference:

0 Comments

To make a comment you have to login