Loading...
Loading...
Build ASP.NET Core Web APIs with .NET 10 (C# 14.0). Supports project scaffolding, CRUD operations, Entity Framework integration, dependency injection, testing with xUnit, Docker containerization, and following 2025 best practices. Use when creating REST APIs, microservices, backend services, implementing CRUD operations, setting up Entity Framework, adding authentication/authorization, or containerizing .NET applications. Triggers on .NET, ASP.NET Core, C#, Web API, REST API, microservices, dotnet, csharp development tasks.
npx skill4agent add racar/racar_agent_skills dotnet-webapiscripts/new_api.sh <project_name> [output_directory]scripts/new_api.sh ProductsApi
cd ProductsApi
dotnet build
dotnet run --project ProductsApi.Apiscripts/new_api.sh MyApi ./projectsMyApi.ApiMyApi.Testsscripts/add_entity.sh <entity_name> <project_path>scripts/add_entity.sh Product ./MyApi
scripts/add_entity.sh Customer ./MyApiModels/Product.csServices/IProductService.csServices/ProductService.csControllers/ProductController.csGET /api/Product - Get all
GET /api/Product/{id} - Get by ID
POST /api/Product - Create
PUT /api/Product/{id} - Update
DELETE /api/Product/{id} - Deletescripts/add_package.sh <project_path> <package_name|preset># Entity Framework with PostgreSQL
scripts/add_package.sh ./MyApi ef-postgres
# Entity Framework with SQL Server
scripts/add_package.sh ./MyApi ef-sqlserver
# JWT Authentication
scripts/add_package.sh ./MyApi auth
# FluentValidation
scripts/add_package.sh ./MyApi validation
# Individual package
scripts/add_package.sh ./MyApi Newtonsoft.Jsonscripts/generate_dockerfile.sh <project_path>scripts/generate_dockerfile.sh ./MyApidocker-compose up -d
docker-compose logs -f api// Program.cs
builder.Services.AddOpenApi();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi(); // /openapi/v1.json
}builder.Services.AddOutputCache();
app.UseOutputCache();
[OutputCache(Duration = 300)]
[HttpGet]
public async Task<IActionResult> GetAll()builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("api", config =>
{
config.PermitLimit = 100;
config.Window = TimeSpan.FromMinutes(1);
});
});scripts/new_api.sh OrderService
cd OrderServicescripts/add_entity.sh Order .
scripts/add_entity.sh OrderItem .scripts/add_package.sh . ef-postgresdotnet build
dotnet run --project OrderService.Apidotnet testscripts/generate_dockerfile.sh .
docker-compose up// Data/ApplicationDbContext.cs
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options) { }
public DbSet<Product> Products => Set<Product>();
}
// Program.cs
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
// appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Database=mydb;Username=postgres;Password=postgres"
}
}dotnet ef migrations add Initial --project MyApi.Api
dotnet ef database update --project MyApi.Api// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
app.UseAuthentication();
app.UseAuthorization();
// Protect endpoints
[Authorize]
[HttpGet("admin")]
public IActionResult AdminOnly() => Ok("Admin data");[ApiController]
[Route("api/[controller]")]
public class ProductController : ControllerBase
{
private readonly IProductService _service;
private readonly ILogger<ProductController> _logger;
// Constructor injection
public ProductController(
IProductService service,
ILogger<ProductController> logger)
{
_service = service;
_logger = logger;
}
// Documented endpoints
/// <summary>
/// Get all products
/// </summary>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<Product>>> GetAll()
// Proper status codes
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Product>> Create(Product entity)
{
var created = await _service.CreateAsync(entity);
return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
}
}// Interface
public interface IProductService
{
Task<IEnumerable<Product>> GetAllAsync();
Task<Product?> GetByIdAsync(int id);
Task<Product> CreateAsync(Product entity);
Task<Product?> UpdateAsync(int id, Product entity);
Task<bool> DeleteAsync(int id);
}
// Implementation with business logic
public class ProductService : IProductService
{
// In-memory for demo, replace with repository/DbContext
private readonly List<Product> _entities = new();
public async Task<Product> CreateAsync(Product entity)
{
entity.Id = _nextId++;
entity.CreatedAt = DateTime.UtcNow;
_entities.Add(entity);
return entity;
}
}public class ProductsEndpointTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient _client;
public ProductsEndpointTests(WebApplicationFactory<Program> factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task GetAll_ReturnsSuccessStatusCode()
{
var response = await _client.GetAsync("/api/products");
response.EnsureSuccessStatusCode();
}
}dotnet test
dotnet test --logger "console;verbosity=detailed"references/api_best_practices.mdreferences/testing_patterns.mdreferences/common_packages.md# Create project
scripts/new_api.sh InventoryApi
# Add entities
scripts/add_entity.sh Product ./InventoryApi
scripts/add_entity.sh Category ./InventoryApi
# Add database
scripts/add_package.sh ./InventoryApi ef-postgres
# Run
cd InventoryApi
dotnet run --project InventoryApi.Api# Create and setup
scripts/new_api.sh OrderService
scripts/add_entity.sh Order ./OrderService
scripts/add_package.sh ./OrderService ef-postgres
scripts/generate_dockerfile.sh ./OrderService
# Deploy
cd OrderService
docker-compose up -dscripts/new_api.sh SecureApi
scripts/add_entity.sh User ./SecureApi
scripts/add_package.sh ./SecureApi auth
scripts/add_package.sh ./SecureApi validationdotnet --version # Should be 10.xASPNETCORE_HTTP_PORTS=5001 dotnet run --project MyApi.Apidocker psdotnet ef database update --verbose --project MyApi.Apipostgres-querypostgres-backup-restoreruby-rails