.NET Core  

Building a Modern Microservices Application with .NET Core, Angular 20, Docker, and Azure

1. Project Overview

MicroservicesDemo - consists of three backend services and one frontend application:

├── UserService/ # Handles user registration, login, JWT authentication

├── ProductService/ # CRUD operations for products

├── OrderService/ # CRUD for orders, communicates with ProductService

├── Frontend/ # Angular 20 frontend application

├── docker-compose.yml # Local orchestration for all services

Technology Stack

LayerTechnology
Backend.NET Core 7 API + EF Core + JWT Auth
FrontendAngular 20
DatabaseMS SQL Server (one per service)
ContainerizationDocker + Docker Compose
Cloud DeploymentAzure App Service + Azure SQL + ACR
TestingPostman

2. Backend Microservices

UserService

  • Provides register and login endpoints.

  • Issues JWT tokens for authenticated access.

  • Uses EF Core with its own UserDb.

Minimal example

public class User { public int Id { get; set; } public string Email { get; set; } public string Password { get; set; } }
[ApiController]
[Route("api/user")]
public class UserController : ControllerBase {
    private readonly UserDbContext _context;
    private readonly IConfiguration _config;

    public UserController(UserDbContext context, IConfiguration config) { _context = context; _config = config; }

    [HttpPost("register")]
    public async Task<IActionResult> Register(User user) {
        _context.Users.Add(user);
        await _context.SaveChangesAsync();
        return Ok(user);
    }

    [HttpPost("login")]
    public IActionResult Login(User dto) {
        var user = _context.Users.SingleOrDefault(u => u.Email == dto.Email && u.Password == dto.Password);
        if (user == null) return Unauthorized();
        var token = GenerateJwt(user);
        return Ok(new { Token = token });
    }

    private string GenerateJwt(User user) {
        var key = Encoding.ASCII.GetBytes(_config["Jwt:Key"]);
        var token = new JwtSecurityToken(
            issuer: _config["Jwt:Issuer"],
            audience: _config["Jwt:Audience"],
            expires: DateTime.UtcNow.AddHours(1),
            signingCredentials: new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)
        );
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

ProductService

  • Handles CRUD operations for products.

  • Communicates via HTTP if needed with other services.

  • Maintains its own ProductDb.

OrderService

  • Handles CRUD for orders.

  • Can validate products via ProductService HTTP calls.

  • Own database: OrderDb.

3. Angular 20 Frontend

  • Login component stores JWT in localStorage.

  • Product component: list, add, edit, delete.

  • Communicates with backend services using JWT authentication headers.

Dockerfile Example:

FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build --prod

FROM nginx:alpine
COPY --from=build /app/dist/frontend /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

4. Local Docker Setup

docker-compose.yml orchestrates all services:

version: '3.8'
services:
  userservice:
    build: ./UserService
    ports: ["5001:80"]
    environment:
      - ConnectionStrings__DefaultConnection=Server=mssql;Database=UserDb;User Id=sa;Password=Your_password123;

  productservice:
    build: ./ProductService
    ports: ["5002:80"]
    depends_on: [userservice]

  orderservice:
    build: ./OrderService
    ports: ["5003:80"]
    depends_on: [userservice, productservice]

  frontend:
    build: ./Frontend
    ports: ["4200:80"]

  mssql:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      SA_PASSWORD: "Your_password123"
      ACCEPT_EULA: "Y"
    ports: ["1433:1433"]

Run locally:

docker-compose up --build

5. Testing APIs with Postman

  • Import PostmanCollection.json.

  • Step 1: Register/Login via UserService → get JWT.

  • Step 2: Use JWT for ProductService and OrderService requests.

  • Capture screenshots of CRUD operations for documentation.

6. Azure Deployment Steps

Step 1. Create Azure Resources

az login
az group create --name MicroservicesDemoRG --location eastus
az acr create --resource-group MicroservicesDemoRG --name microservicesacr --sku Basic
az sql server create --name usersqlserver --resource-group MicroservicesDemoRG --location eastus --admin-user azureuser --admin-password YourStrongPassword123
az sql db create --resource-group MicroservicesDemoRG --server usersqlserver --name UserDb --service-objective S0
# Repeat for ProductDb and OrderDb

Step 2. Push Docker Images

az acr login --name microservicesacr
docker tag userservice microservicesacr.azurecr.io/userservice:latest
docker push microservicesacr.azurecr.io/userservice:latest
# Repeat for ProductService, OrderService, Frontend

Step 3. Deploy to App Service

az appservice plan create --name MicroservicesPlan --resource-group MicroservicesDemoRG --sku B1 --is-linux
az webapp create --resource-group MicroservicesDemoRG --plan MicroservicesPlan --name userserviceapp --deployment-container-image-name microservicesacr.azurecr.io/userservice:latest
# Repeat for other services and frontend

Step 4. Configure Environment Variables

az webapp config appsettings set --resource-group MicroservicesDemoRG --name userserviceapp --settings ConnectionStrings__DefaultConnection="Server=tcp:usersqlserver.database.windows.net,1433;Initial Catalog=UserDb;User ID=azureuser;Password=YourStrongPassword123;"
# Repeat for other services

7. Key Best Practices

  • Each microservice has independent database for data isolation.

  • JWT ensures secure communication between frontend and services.

  • Docker Compose simplifies local development and testing.

  • Cloud deployment uses ACR + App Service + Azure SQL, scalable and production-ready.