Generating .NET Web API Microservices from Template
Inspired by a colleague’s efficient approach to standardizing microservices, I created a bash script template generator for .NET Web API projects. The script creates a standardized architecture with controllers, services, repositories, and data models, setting up Entity Framework Core and Swagger UI in the process.
With a single command:
bashCopy./create-api.sh ProjectName
You get a complete microservice structure following clean architecture principles. The template includes a layered design, basic User entity implementation, and an in-memory database for rapid development.
This approach ensures all microservices follow the same structure, making maintenance and cross-service development more straightforward for team members.
Find the template and documentation on GitHub: dotnet-webapi-template-script
Or here:
#!/bin/bash
if [ -z "$1" ]
then
echo "Please provide a project name"
echo "Usage: ./create-api.sh ProjectName"
exit 1
fi
PROJECT_NAME=$1
# Create directory for solution
mkdir $PROJECT_NAME
cd $PROJECT_NAME
# Create solution and project
dotnet new sln -n $PROJECT_NAME
dotnet new webapi -n $PROJECT_NAME
dotnet sln add $PROJECT_NAME/$PROJECT_NAME.csproj
cd $PROJECT_NAME
# Create directory structure
mkdir -p Contracts
mkdir -p Controllers
mkdir -p DataModel/Entities
mkdir -p Repositories
mkdir -p Services
# Create files
echo "namespace $PROJECT_NAME.Contracts
{
public class UserDto
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
}" > Contracts/UserDto.cs
echo "namespace $PROJECT_NAME.DataModel.Entities
{
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
}" > DataModel/Entities/User.cs
echo "using Microsoft.EntityFrameworkCore;
using $PROJECT_NAME.DataModel.Entities;
namespace $PROJECT_NAME.DataModel
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
Database.EnsureCreated();
}
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasKey(u => u.Id);
// Seed some data
modelBuilder.Entity<User>().HasData(
new User { Id = 1, Username = \"user1\", Email = \"user1@example.com\" },
new User { Id = 2, Username = \"user2\", Email = \"user2@example.com\" }
);
}
}
}" > DataModel/ApplicationDbContext.cs
echo "using $PROJECT_NAME.DataModel;
using $PROJECT_NAME.DataModel.Entities;
namespace $PROJECT_NAME.Repositories
{
public class UserRepository
{
private readonly ApplicationDbContext _context;
public UserRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task<User> GetByIdAsync(int id)
{
return await _context.Users.FindAsync(id);
}
}
}" > Repositories/UserRepository.cs
echo "using $PROJECT_NAME.Contracts;
using $PROJECT_NAME.Repositories;
namespace $PROJECT_NAME.Services
{
public class UserService
{
private readonly UserRepository _userRepository;
public UserService(UserRepository userRepository)
{
_userRepository = userRepository;
}
public async Task<UserDto> GetUserByIdAsync(int id)
{
var user = await _userRepository.GetByIdAsync(id);
if (user == null) return null;
return new UserDto
{
Id = user.Id,
Username = user.Username,
Email = user.Email
};
}
}
}" > Services/UserService.cs
echo "using Microsoft.AspNetCore.Mvc;
using $PROJECT_NAME.Contracts;
using $PROJECT_NAME.Services;
namespace $PROJECT_NAME.Controllers
{
[ApiController]
[Route(\"[controller]\")]
public class UsersController : ControllerBase
{
private readonly UserService _userService;
public UsersController(UserService userService)
{
_userService = userService;
}
[HttpGet(\"{id}\")]
public async Task<ActionResult<UserDto>> Get(int id)
{
var user = await _userService.GetUserByIdAsync(id);
if (user == null) return NotFound();
return user;
}
}
}" > Controllers/UsersController.cs
echo "using Microsoft.EntityFrameworkCore;
using $PROJECT_NAME.DataModel;
using $PROJECT_NAME.Repositories;
using $PROJECT_NAME.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseInMemoryDatabase(\"$PROJECT_NAME\"));
builder.Services.AddScoped<UserRepository>();
builder.Services.AddScoped<UserService>();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(\"/swagger/v1/swagger.json\", \"$PROJECT_NAME API V1\");
c.RoutePrefix = string.Empty;
});
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();" > Program.cs
# Add packages
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package Swashbuckle.AspNetCore
echo "Solution and project $PROJECT_NAME created successfully! Run with 'dotnet run' and visit https://localhost:5001/swagger"