How Do You Get Started With Microservices?
In this article, we’ll try to address the question of where to start and what the crucial aspects are that we need to consider with microservices.
Join the DZone community and get the full member experience.
Join For FreeWelcome fellow explorer! It seems like you are deep into microservices already. It must have taken a lot of effort to find this article!
Let’s start with a heart-felt congratulations first!
To honor your efforts, I’m going to get straight to the point.
Deciding whether you want to adopt a microservices-based architecture is hard. Embarking on the journey to build one is even harder!
How do you decide where to start?
What all should one consider? Should you start with a monolith and then break it down into microservices? How do you break down your services? What are the common pitfalls that can come your way?
There are so many questions one needs to answer.
In this article, we’ll try to address the questions of where to start and what the crucial aspects we need to consider are when getting started with microservices.
Step 1: What’s Your Objective of Going Ahead With Microservices?
I’m sure you want to punch me in the face right now. It’s almost like taking a step back!
I’m sure you have done your research. But, let’s answer this one more time.
Why do you want a microservices-based architecture in the first place?
Is it to make your application scalable? Or is it for making things more reliable?
The answer to that question decides whether you should go ahead with building a microservices-based architecture or not.
If you are looking for scale and/or reliability, you are better off building a monolith.
Trust me when I say that. In fact, many are considering going back to monoliths in 2020. Istio, a popular Kubernetes based service mesh, has already made the switch.
So, when do microservices make sense?
Consider microservices when you want development agility at scale.
Yup, that’s right!
Microservices achieves agility by breaking a large project down into smaller applications and encouraging smaller, more independent teams.
The words smaller applications and independent teams are important here.
All our efforts to get started with microservices are concentrated around them.
To conclude, opt for microservices only when you want to rapidly ship out new features while your app and organization are growing rapidly in size.
That’s the real secret to getting started with microservices!
Step 2: Breaking Down Your App into the Right-Sized Components
This is more difficult than it sounds. It requires careful planning and consideration to get it right.
The burning question is, What functional pieces do we break our app down to? How small does a service need to be? What do we even mean by the word 'micro?'
I personally think that the term microservice is misleading. It tempts us to think of these services as being 'micro' or as small as possible.
This isn’t the right way to get started with microservices.
Let’s Look at a Real-World Use-Case
I’m going to take the example of an app like Medium to explain the challenges of developing microservices with misplaced functionalities.
At its core, Medium is a blogging platform.
You and I can sign up on Medium as users. By default, we are on a free subscription plan. As you may know, users can opt for a paid plan to view all the metered or premium posts.
I might be inaccurate, but try to not focus on Medium’s business model. We should be more focused on the use-case.
Let’s say I have two microservices to handle this — users
and billing
. The users
microservice deals with user management along with recording the plan each user has activated. The billing
microservice handles everything to do with a payment gateway.
The problem arises whenever a user needs to be upgraded from the free to the paid plan. What we require now is a distributed transaction across two microservices.
We need to create a new billing subscription (in the billing
microservices) and update the plan of the user (in the users
microservices).
As you may know, transactions are a difficult topic to get right. And, here, we are talking about a distributed one across two different microservices!
There are ways to get around this problem. You might be aware of them. I’m going to talk about one such solution in my next point. But, let’s look at the bigger picture here.
Mutations spanning multiple microservices must be avoided.
Don’t make your microservices so small that you end up with such a scenario too often.
Making your microservices too large doesn’t help either. It might beat the purpose of microservices altogether.
Always design your microservice as an independent SaaS offering with all external APIs being completely out of your control
Comparing microservices with a SaaS offering may be going a bit overboard, but I really like that analogy.
You would want everything you depend on to deliver your APIs to be in that microservice itself. Even if it means you end up denormalizing your schema.
This doesn’t mean all data should be served from your database. It is okay to fetch data from other services or external APIs. In that case, you act more as a presentational or aggregator service.
This brings me to my next point.
The aspect of losing control or influence over external APIs is important. You cannot assert influence over other teams and have to accept the API contract/schema provided by them.
This applies to other teams as well.
I’m not saying that you can evade all communication between teams. Each API design draft has to be thought of collectively. But, the implementation flexibility will reside with each team.
This forces a culture of working around the existing API and minimizes cross-team interference.
I know this might sound a bit too restrictive. I totally agree with you; it kind of is.
With time, your teams will develop the mindset and the right processes to implement and get started with microservices-based architectures.
They will start synchronizing their releases with others. Things will start working like one well-oiled engine composed of several independent parts.
Remember this,
Microservices based architecture is a design pattern and not a framework.
And, no design pattern can be successfully implemented without imbibing the right mindset.
This point turned out to be a bit too heavy. Let’s move on to the next one.
Step 3: Use Eventing as Glue
Eventing is a great way to glue or stitch microservices together while keeping them fairly decoupled.
I know what you are thinking. I just used the words stitch together and decoupled in the same sentence.
Now that I think about it, it does sound funny, but hear me out once.
Eventing is a mechanism to synchronize different services. It does so by emitting events, which other services, called targets, can subscribe to. Its semantics are similar to a pub-sub system in that regard.
Events can be generated by various sources — database mutations, file storage operations, function invocations, or manually via an API.
Services interested in these events can trigger certain actions based on them — sending emails on user signups, updating internal state, etc.
If you think about it, we can handle the cross-service transaction problem I discussed earlier (in the Medium example) by using eventing. Let me know in the comments how you would solve it.
I’d strongly suggest you read up on what eventing is and how it fits with microservices to know more.
A great characteristic about eventing is that it decouples the source from the target.
This means you can have zero or hundreds of targets subscribed to a particular event without affecting the source at all.
Functions as a Service are a great fit for this task.
In short, eventing provides a great mechanism to synchronize different microservices.
In my experience, most events are triggered via the data layer.
Most cloud providers support this for their native solutions. For example, AWS DynamoDB and Google Firestore all trigger events on mutations.
If you would like to explore an open-source eventing system that is cross-platform, i.e. works with open source databases, check out Space Cloud - An open-source Firebase + Heroku.
Step 4: Consider Using GraphQL at the API Layer
This one should be fairly straight forward.
Your clients or end-users would require information from multiple services to populate a single page. This article itself is touching the users
and posts
microservices.
This means you’ll be required to write an aggregator service to do anything meaningful. This service would join data from multiple sources and make it available to the end-user.
I think you know where I am going from here.
The scenario explained above is the perfect use case for GraphQL.
Its use extends well beyond your end-users. Your microservices can use the GraphQL layer as well.
You could put your databases and microservices behind a GraphQL API creator like Space Cloud. This would give you a consistent access pattern for data sources.
Okay, okay! I’m getting a bit too excited!
Let's continue focusing on getting started with microservices for now.
Bonus: Start With a Monolith
I see you’ve got your guns all loaded up and ready to fire.
After all this information, I’m asking you to start with a monolith. I would be angry with myself if I didn’t know what’s coming next.
If you are working with smaller teams, having multiple microservices is an unnecessary burden.
Let’s be honest, at that scale, it isn’t giving you any benefits.
Instead of having multiple microservices and increasing your DevOps complexity, you can have a single codebase for all your microservices; all of them packed into a single binary.
Don’t get me wrong here, I’m not asking you to disregard any of the points I’ve covered earlier.
What I am asking is about building a monolith with all the practices we have discussed till now.
This implies that each module in our monolith can talk to each other via HTTP (or gRPC) only. Each module will have its own set of tables that other modules can not access.
I guess you get the point.
The process of breaking down the monolith, in that case, should be fairly simple, provided all the above principles are followed diligently.
And, it gives you ample opportunity to decide which functionality should be assigned to which module.
If things go as planned, each module will grow up to be an independent microservice someday. And, that day shall come soon. I feel like a proud father already!
It's Time to Finally Get Started With Microservices!
I really wish you success in this journey of getting started with microservices.
As you may have noticed, I’ve tried really hard ranking for the phrase getting started with microservices, and the term microservices.
It would be great if you could help me as well by sharing this post on Twitter.
Don’t forget to star us on GitHub!
Published at DZone with permission of Noorain Panjwani, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments