Microservices Service communications
In this post I want to explore with an example how microservices communicates with each other in ASP.NET core. In this post each microservice exposes a set of HTTP endpoints that other microservices or clients can call to perform specific actions or retrieve data.
Different Communication patterns in microservices:
- HTTP/RESTful APIs:
- Microservices expose HTTP endpoints and communicate with each other via RESTful API calls. This is one of the most common and widely used communication patterns in microservices architecture.
- Each microservice exposes a set of HTTP endpoints that other microservices or clients can call to perform specific actions or retrieve data.
- Message Queues/Message Brokers:
- Microservices communicate asynchronously through message queues or message brokers such as RabbitMQ, Apache Kafka, or Amazon SQS.
- Microservices produce messages to a queue or topic, and other microservices consume these messages to perform tasks or respond to events.
- Message queues enable loose coupling between microservices and can help improve scalability and fault tolerance.
- gRPC:
- gRPC (Google Remote Procedure Call) is an open-source RPC framework developed by Google that enables efficient communication between microservices.
- gRPC uses HTTP/2 as its transport protocol and Protocol Buffers (protobuf) as its interface definition language (IDL).
- It provides features such as bidirectional streaming, authentication, and automatic code generation, making it suitable for building efficient and high-performance microservices.
- Service Mesh:
- Service mesh architectures such as Istio, Linkerd, and Consul Connect provide a dedicated infrastructure layer for handling communication between microservices.
- Service mesh typically includes features such as service discovery, load balancing, circuit breaking, and encryption.
- It allows for more advanced communication patterns such as mutual TLS (mTLS), distributed tracing, and traffic management.
- Remote Procedure Calls (RPC):
- Microservices can communicate through remote procedure calls (RPC) using protocols like HTTP, gRPC, or Thrift.
- In RPC communication, a client invokes a procedure or method on a remote service, and the service executes the requested operation and returns a response.
- RPC frameworks handle the serialization, deserialization, and transport of messages between microservices.
Each communication pattern has its own advantages and trade-offs, and the choice of communication mechanism depends on factors such as performance requirements, scalability, complexity, and the specific use case of the microservices architecture.
In this post we are using HTTP/RESTful APIs:
Creating Projects and soltuion in .NET 8
Create three projects in Visual studio with template ASP.NET Core Web Api.
- ApiGateway
- Service1
- Service2
Project ApiGateway
Copy paste the following code to Program.cs in the ApiGateway project:
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddHttpClient();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "API Gateway", Version = "v1" });
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API Gateway");
});
}
app.MapControllers();
app.Run();
Copy and paste the following code to the GatewayController.cs in the ApiGateway project:
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace ApiGateway
{
[ApiController]
[Route("api/[controller]")]
public class GatewayController : ControllerBase
{
private readonly HttpClient _httpClient;
public GatewayController(IHttpClientFactory httpClientFactory)
{
_httpClient = httpClientFactory.CreateClient();
}
[HttpGet("service1")]
public async Task<ActionResult<string>> GetFromService1()
{
//var response = await _httpClient.GetStringAsync("http://localhost:5001/api/service1");
// if it is not working, you should check the terminal to see which port is listening then chang to it.
var response = await _httpClient.GetStringAsync("http://localhost:5080/api/service1");
return response;
}
[HttpGet("service2")]
public async Task<ActionResult<string>> GetFromService2()
{
//var response = await _httpClient.GetStringAsync("http://localhost:5002/api/service2");
// if it is not working, you should check the terminal to see which port is listening then chang to it.
var response = await _httpClient.GetStringAsync("http://localhost:5072/api/service2");
return response;
}
}
}
Project Service1
Copy paste the following code to the Program.cs in the Service1 project:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapGet("/api/service1", () => "Response from Service1");
app.Run();
Copy and paste the following code to the Service1Controller.cs in the project Service1:
using Microsoft.AspNetCore.Mvc;
namespace Service1
{
[ApiController]
[Route("api/[controller]")]
public class Service1Controller : ControllerBase
{
[HttpGet("service1")] // Define the route for Service1 endpoint
public ActionResult<string> Get()
{
return "Response from Service1";
}
}
}
Project Service2
Copy and paste the following code to the Program.cs file of Service2:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
//app.MapControllers();
app.MapGet("/api/service2", () => "Response from Service2");
app.Run();
Copy and paste following code to the Service2Controller.cs in project Service2:
using Microsoft.AspNetCore.Mvc;
namespace Service2
{
[ApiController]
[Route("api/[controller]")]
public class Service2Controller : ControllerBase
{
[HttpGet("service2")] // Define the route for Service1 endpoint
public ActionResult<string> Get()
{
return "Response from Service2";
}
}
}
Add all three projects to a solution (e.g. MicroservicesCommunication)
The structure of solution shall look like as follow:
Configure and run the all three Services in the Visual studio by right click on the solution and select Properties and check the: Multiple startup project and set all three project to start as following image:
Run the solution then all three projects are running and shows the Swagger UI as shown in the following:
from the figure above you can see the three Swagger UI for ApiGateway and the two Serives as come up and their terminal shows which prots are listening.
In the API Gateway Swagger UI, explore the Get: api /ApiGateway/Service1 and press to the Try it out then Execute the result shall be displays as follow:
You can run for Get: api /ApiGateway/Service2.
Even you can run Service1 and Service2 Swagger UIs.
As we see from ApiGateway we can communicate to the other Services.
ApiGateway in the GatewayController.cs uses two URLs: http://localhost:5080/api/service1, and http://localhost:5080/api/service2 to access to the API Route to API endpoit /api/serivce1 and /api/service2 using ports: 5080 and resp. 5072.
This portes shall be seen also in the terminals of Service1 and Service2.
In case access to the services is not possible from Gateway then you should look to the pors in the terminals and change the ports in the GatewayController.cs URLs.
All the Source code is in my Github
Conclusion
In this post, I have created ApiGateway and two Services in ASP.NET Core Web API and implemented them and showed how you can communicate from ApiGateway to the other Services in the Microservices architecture.
This was a simple communication of Services in HTTP/RESTful APIs: and you can develop further each service and add more Services, database access and more.
In the next post will implement a microservice using ASP .NET Core
This post is part of “Microservices-Step by step”.