AUTO1 Group

Yet another story about a monolith and microservices

Dmytro Malyshenko

By Dmytro Malyshenko

Team Lead Software Engineer

< Back to list
Coding Dec 4 2018

The story about how one hackathon project sped up the development of our back office system by 2 days per feature. The story about how we enabled our teams to develop in the newest technology-agnostic stack by extending the architecture of legacy monolith application. The story about how we enabled our teams to extend a monolith back office without touching it.

Once upon a time, there was a startup which was built as a monolith...

In AUTO1, as in the majority of other companies, we also have a back-office software (aka “Admin”) where our employers can manage our business operations. We’ve got a lot of business processes, and therefore a lot of business logic put into the code.

A couple of facts about Admin:

  • it's a web-based software, built with PHP
  • the first commit dates back to 1st of Aug, 2013, by the current VP of Engineering
  • it was built on the Silex framework, using ORM (doctrine) with direct connection to MySQL
  • 32.5k commits
  • ~100 contributors
  • ~600k lines of code
  • at some point in time, we had 4 teams dedicated only to Admin

From these facts, you can see, that what the thing we’re talking about - it's a typical monolith.

An authentication between requests was handled with a very common approach for PHP applications - PHP Sessions. With this approach the session identifier for the current user is put in a cookie, and on the server side, the session data is somehow stored as a document.

Monolith PHP Application

The moment any monolith is afraid of

Then we’ve got our first microservices. Some business logic started to live its own life. And of course, our Admin should have had some control over it. So our Admin started to interact with our microservices, and initially it was treated more or less as a third-party API.

First microservices

Our microservices are located behind an API gateway (we call it GateKeeper), every authenticated request should be signed with an OAuth token to get through it. Also, every request should be signed by the client application with an API key.

Admin has become one of the external clients of microservices API. It had its own API key, every user was obtaining an OAuth token, which is kept in a session document, as a part of a session data.

Months were passing. In general, an architecture stayed the same, apart from the fact the number of our microservices increased. And increased a lot.

More microservices

More and more business logic was covered by services while less and less logic was implemented in Admin. Then at some point were realized, that what happens in Admin - it’s just a proxying of requests to a gateway. The usual code for a new feature was more or less - send a request to the Gateway, get a request, send this request to a front-end client. Not the most exciting engineering work ever.

Moreover, we’ve got another complication - some teams without any PHP engineer had to add some new features to back-office. For this, one needed to create a proxying code, and for this one would need some support from another team.

There should be a better way

So we’ve started to think of possibilities to send requests to the Gateway directly from Frontend, in order to avoid a necessity to make any implementation in Admin every time we do a new feature. And challenges were:

  • we can't get rid of Admin. Even though it was getting almost no new features, there were a lot of old ones. And usually, we were adding new widgets into old pages.
  • we can’t get rid of sessions - our old Admin features depend on them
  • we don’t want to keep two mechanisms of authentication on a Frontend side. I.e. we don’t want to introduce anything alongside sessions, in order to avoid consistency issues between the user session and our permissions model.

Then unexpectedly a group of our engineers (Mikhail, Oleg, Alexey and Andy - thank you, guys!) came out with a prototype of Vigolante, as a Hackathons project.

Vigolante - a mix of GO and VIGILANTE (sp.), which means a guard.

Vigolante

The idea behind it can fit in one sentence: it’s an authentication layer, which uses the same cookie as Admin, gets a session identifier from a frontend request, connects to the sessions storage (Memcached), fetches a session data, gets a OAuth token from the data and, enriches the initial request with the token and then forwards it to a Gateway.

Quite a simple flow, but once in place helped us to save a lot of development time in order to deliver new features to Admin. From now on, we don’t need to make any changes in Admin, when we need to send a request to a microservice from Frontend.

We have chosen Golang as an underlining technology to build the project. The reasons are:

  • it's fast. It adds only about 10ms of overhead per request.
  • it's small. The resulting docker image is only 1MB big!
  • it's fun. We gave ourselves a break from Java or PHP.

Basically, the project was developed by the efforts of 4 engineers in a bit more than one day. We are proud to say, that this time was not just for coding but also for taking care of bringing the software to production; things as:

  • build/release pipelines (as a code). We use Jenkins in AUTO1, and our pipelines should be delivered in a form of Groovy-based Jenkins DSL code.
  • Infrastructure (as a code). We using AWS services, and the application was prepared as a Docker container, ECR was used for as a container registry, ECS as a platform to run a container. All this was described in a form of Terraform configuration
  • Integration with platform, done in a form of a listener for Application Load Balancer (ALB) for main Admin platform host. So, basically, every request with a certain prefix was directed to Vigolante, instead of Admin.

There were few things yet to be resolved (such an implementation of mechanisms of refreshing of OAuth tokens, also there were some problems with encryption of PHP sessions from Memcached), but those were successfully resolved; one month later we released the first feature relying on Vigolante to production.

Feeling proud and fulfilled, we could now focus our attention on the our engineering challenges.

Stories you might like:
CodingJul 2
By Nicholas Peretti

Create forms at scale with Formik and Yup

CodingJun 24
By Wojciech Oroński

Yet another case study of developing serverless apps with PHP.

CodingApr 4
By Chirag Swadia

How we use ES6 generators instead of thunk to simplify our React Redux application code and...