ASP.NET Core  

How Do Microservices Communicate in .NET 10?

Introduction

As modern applications continue to grow in size and complexity, microservices architecture has become the preferred approach for building scalable and maintainable systems. Instead of deploying a single large application, teams now decompose functionality into smaller, independently deployable services. In a monolithic application, communication is simple and fast—method calls within the same process. In microservices, communication happens over the network, which brings latency, partial failures, versioning concerns, and security considerations.

In this article, I will explore the most widely used communication mechanisms in microservices, explain when and why each should be used, and demonstrate their implementation in .NET 10.

Understanding Microservices Communication Styles

Microservices typically communicate using two fundamental styles:

1. Synchronous Communication

The calling service waits for an immediate response from another service. Examples: REST APIs, gRPC.

2. Asynchronous Communication

The calling service sends a message or event and continues processing without waiting for a response. Examples: Message queues, event streaming platforms.

Most production systems use a combination of both, depending on business needs and performance requirements.

1_k-rQpq1GQFtsgQERWYwKqg

1. RESTful APIs (HTTP-Based Communication)

REST remains the most common and accessible communication mechanism in microservices. It relies on standard HTTP methods and usually exchanges data in JSON format.

Despite newer alternatives, REST continues to be relevant due to its simplicity, tooling support, and compatibility with browsers and external clients.

When REST Is the Right Choice

  • Client-facing or public APIs

  • Simple request–response workflows

  • Scenarios where readability and debuggability matter

  • Integration with third-party systems

RestAPI

Example: Product Microservice Using ASP.NET Core (.NET 10)

[ApiController]
[Route("api/products")]
public class ProductController : ControllerBase
{
    [HttpGet]
    public IActionResult GetProducts()
    {
        return Ok(new[] { "Laptop", "Tablet", "Mobile" });
    }

    [HttpPost]
    public IActionResult CreateProduct(Product product)
    {
        return Ok(product);
    }
}

Why REST Still Works Well

  • Easy to understand and maintain

  • Mature ecosystem (Swagger, OpenAPI, Postman)

  • Language and platform independent

Limitations to Be Aware Of

  • JSON serialization increases payload size

  • Higher latency for internal service-to-service calls

  • Tight coupling due to synchronous request–response flow

2. gRPC – High-Performance Internal Communication

gRPC is designed for efficient, low-latency communication between internal services. It uses Protocol Buffers (Protobuf) for binary serialization and runs over HTTP/2, making it significantly faster than REST.

With .NET 10, gRPC continues to be a first-class citizen, especially for service-to-service communication inside a controlled environment.

Ideal Use Cases for gRPC

  • Internal microservice communication

  • High-throughput systems

  • Real-time or streaming scenarios

  • Strict API contract enforcement

gRPCGRPC1

Define the Service Contract (greet.proto)

syntax = "proto3";

option csharp_namespace = "GrpcService1";

package greet;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply);
}

Implement gRPC Service in .NET 10

namespace GrpcService1.Services
{
    public class GreeterService(ILogger<GreeterService> logger) : Greeter.GreeterBase
    {
        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            logger.LogInformation("The message is received from {Name}", request.Name);

            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}

Key Benefits

  • Very fast serialization and transport

  • Strongly typed, contract-first design

  • Built-in support for streaming

Trade-Offs

  • Payloads are not human-readable

  • Requires tooling for debugging

  • Limited direct browser support

3. Message Queues – Asynchronous and Event-Driven Communication

Message queues enable asynchronous communication, allowing services to exchange messages without knowing about each other’s availability or location. This approach is fundamental to event-driven architectures.

Technologies like RabbitMQ, Apache Kafka, and cloud-based queues are commonly used with .NET microservices.

When Message Queues Are the Best Fit

  • Background processing

  • Event publishing (e.g., OrderCreated)

  • Loose coupling between services

  • High resilience and fault tolerance

Example: RabbitMQ Producer in .NET 10

var factory = new ConnectionFactory { HostName = "localhost" };

using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.QueueDeclare("productQueue", false, false, false);

var body = Encoding.UTF8.GetBytes("ProductCreated");

channel.BasicPublish("", "productQueue", null, body);

Why Teams Choose Message Queues

  • Services are loosely coupled

  • Improved system stability

  • Easy horizontal scaling

Challenges

  • Increased infrastructure complexity

  • Harder end-to-end tracing

  • Requires idempotent message handling

4. Apache Kafka – Event Streaming at Enterprise Scale

Apache Kafka is a distributed event streaming platform built for massive scale. Unlike traditional queues, Kafka stores events durably and allows multiple consumers to read them independently.

Kafka is often used when events are core to the business domain.

Common Kafka Use Cases

  • Event sourcing

  • Audit logs

  • Real-time analytics

  • Data pipelines across systems

Kafka works best when teams embrace event-driven thinking rather than request–response models

Comparison

FeatureRESTgRPCMessage Queues
Communication StyleSynchronousSync + StreamingAsynchronous
PerformanceModerateVery HighEvent-based
CouplingMediumTightLoose
Best Use CaseExternal APIsInternal servicesEvents & background tasks

Final Thoughts

Choosing how microservices communicate is a long-term architectural decision, not just a technology choice.

  • REST prioritizes simplicity and accessibility

  • gRPC delivers speed and contract safety

  • Message queues enable resilience and scalability

Modern systems built with .NET 10 often combine all three approaches to meet evolving business and technical demands.