loading...
Cover image for Building microservices, does size matter?
.NET

Building microservices, does size matter?

spboyer profile image Shayne Boyer ・3 min read

A few months ago I had a chance to sit down and chat with Glenn Condron and Ryan Nowak from the ASP.NET Team about the new things coming in .NET 3.0 for Microservices.

Topics

  • 00:22 - What’s the goal with the Microservice templates in .NET Core 3.0?
  • 03:05 - What are the new Worker templates?
  • 06:57 - What’s happening with gRPC in .NET Core 3?
  • 11:47 - How we developers choose between gRPC and Web APIs?

Resources

Does Size Matter for Microservices?

It got me thinking more about microservices in general and how to think of them. Is "micro" the right prefix here? Are they actually small? Probably not.

The term is more around the responsibility, deployment (not the size of), manageability, service boundary, and development team.

Hello World

Not to retract, but what is the minimal realistic service in .NET Core we can write to get simply produce a "Hello World"?


public class Service
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Service>();
            });

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync("Hello, world!");
            });
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

Here, a host is created with EndpointRouting set to handle the "/" route and return "Hello, world!".

Using dotnet run you could browse to http://localhost:5000 and see the Hello, world! output to the screen. Not very practical, however, a single responsible service doing the job.

Use the .NET CLI to create a new API template using dotnet new webapi for a more complete template to build on. See tutorial/docs here.

Focus on the job

Building the service should be more about the desire to create a "small focused" services instead of just a small service.

There is a risk vs reward conversation to be had here. The desire to create as many small services as possible in order to adhere to a mantra of microservices approach will lead to a degree of overhead not worth it.

Not sure about you, but every time I step in that pile it hurts...

Bounded contexts

Depending on where you look, listen, read, etc., Domain-Driven Design may come into the picture on how to put together complexity in large systems and it has many great tools.

One term used in DDD is aggregate to describe a cluster or collection of objects treated as a single unit. So in an application where we are handling customer orders, it would make sense for all of the "CustomerOrder" operations and data to be handled by a single service.

However, it is easy to have other "Customer" or "Order" operations bleed into the service. Finding yourself grouping classes or entities instead of the actual capabilities of the services.

Having the ability to maintain and deploy each service/schema independently is a large benefit, and scaling each service on a need basis lends itself in this architecture as well. However, being network chatty is a side effect. Are you ok with a bunch of calls as long as they are super fast in exchange for ease of deployments, scalability and, maintainability?

How small is small?

Is the team small? 6-8 engineers or a handful seems to be an ideal number depending on the application, but large systems have been built by smaller teams and vice versa.

My code use to be measured by the number of lines?

Size on disk? Disk space is cheap some would say.

Containers are getting smaller every day, until you put an app in it.

What are your thoughts?

Discussion

pic
Editor guide
Collapse
jcmrva profile image
Josh M

I worked on a team that thought services should be split along the same lines that equivalent classes might be - the single responsibility advice taken to an extreme. The result: ~50% of the code in each service was boilerplate, intra-service issues were much far harder to debug, huge amounts of wasted time/effort/money, upstream SLAs were failing because of JSON serialization time, etc. That was when I learned the phrase distributed monolith.

In their defense, some of that came from leadership directives: "We'll definitely become the Amazon of ___, so..." (They didn't.)

Sometimes it's okay to mash things together.