11 November 2018
Microservices architecture has become one of the most popular architectural patterns for building scalable, maintainable, and independently deployable applications. With the rise of cloud-native applications and containerization, microservices enable teams to work on individual components independently, allowing for faster delivery and better scalability. In this post, we’ll explore how to build a basic microservice architecture using .NET Core.
What is a Microservice Architecture?
A microservice architecture is a design pattern in which an application is composed of loosely coupled services. Each service is responsible for a specific business capability and is deployed independently. Microservices typically communicate with each other over HTTP or messaging queues, often exposing RESTful APIs.
Benefits of Microservices:
- Scalability: Each service can be scaled independently, based on demand.
- Flexibility: Microservices allow developers to use different technologies and frameworks for different services.
- Resilience: Failure in one service does not necessarily affect other services in the system.
- Faster Development: Teams can work independently on different services, leading to faster feature delivery and iterations.
Setting Up a Basic Microservices Architecture with .NET Core
To build a basic microservice architecture, we’ll focus on creating two independent services using .NET Core:
- User Service: A service responsible for managing user data.
- Product Service: A service that handles product-related operations.
We’ll also look at how these services communicate with each other over HTTP (REST APIs).
Step 1: Create the User Service
Start by creating a new Web API project for the User Service.
dotnet new webapi -n UserService
Inside the UserService
, implement a basic UserController
with a simple endpoint that fetches user details:
public class UserController : ControllerBase
{
[HttpGet("users/{id}")]
public IActionResult GetUser(int id)
{
var user = new { Id = id, Name = "John Doe" }; // Dummy data
return Ok(user);
}
}
This UserController
returns a basic JSON response when accessed via a GET request to /users/{id}
.
Step 2: Create the Product Service
Similarly, create a Product Service:
dotnet new webapi -n ProductService
Inside the ProductService
, implement a basic ProductController
:
public class ProductController : ControllerBase
{
[HttpGet("products/{id}")]
public IActionResult GetProduct(int id)
{
var product = new { Id = id, Name = "Laptop", Price = 1200 }; // Dummy data
return Ok(product);
}
}
This ProductController
returns a simple JSON object for product data.
Step 3: Add Communication Between Microservices
To allow the Product Service to retrieve data from the User Service, you can use HTTP Client to make a call between the services.
In the ProductService
, create an HttpClient
to call the UserService
. First, add IHttpClientFactory
to Startup.cs
for creating HTTP clients:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddControllers();
}
Then, modify the ProductController
to use the HTTP client to call the UserService
:
public class ProductController : ControllerBase
{
private readonly HttpClient _httpClient;
public ProductController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet("products/{id}")]
public async Task<IActionResult> GetProduct(int id)
{
// Call User Service
var userResponse = await _httpClient.GetStringAsync("http://localhost:5000/users/1");
var product = new { Id = id, Name = "Laptop", Price = 1200, User = userResponse };
return Ok(product);
}
}
In this example, when the /products/{id}
endpoint is hit, the ProductService
makes a GET request to the UserService
to fetch user data and combines it with the product data.
Step 4: Running the Microservices Locally
To run both microservices locally:
- Start the UserService:
cd UserService dotnet run
- Start the ProductService:
cd ProductService dotnet run
Both services should be accessible on different ports locally, such as:
UserService
running athttp://localhost:5000
ProductService
running athttp://localhost:5001
Now, when you navigate to /products/{id}
on the ProductService, it should display data from both the product and the user services.
Conclusion
In this post, we have built a simple microservices architecture with .NET Core. We created two independent services — a UserService and a ProductService — and demonstrated how they can communicate with each other via HTTP requests. This is just the beginning of building scalable and resilient systems. As your microservices grow, you can introduce more sophisticated patterns like service discovery, load balancing, fault tolerance, and distributed tracing.
The key takeaway is that .NET Core makes it easy to develop and deploy microservices. Whether you’re building a small app or a large-scale distributed system, .NET Core’s flexibility and performance will serve you well.
Stay tuned for more posts where we’ll dive deeper into microservice topics, like inter-service communication, security, and orchestration!