Language: English | ηΉι«δΈζ
A comprehensive .NET WebAPI development template implementing Clean Architecture, layered architecture, and Result Pattern best practices.
- .NET 8+ SDK
- Docker & Docker Compose (for database and cache test environments)
- Git
-
Clone the project
git clone https://github.com/yaochangyu/api.template.git cd api.template/dotnet-project-template -
Configure environment variables
cp env/local.env .env # Edit .env to set local database connection strings, Redis address, etc. -
Start development environment
docker-compose up -d # Start SQL Server, Redis, etc. dotnet build # Build the solution dotnet run --project src/be/JobBank1111.Job.WebAPI
-
Verify API is running
curl http://localhost:5000/api/health
-
Run tests
dotnet test # Execute all unit and integration tests
api.template/
βββ .claude/ # Development tools & AI assistant guides
β βββ CLAUDE.md # AI assistant behavior rules & plan management
β βββ development-rules.md # Development rules & best practices
β βββ decision-framework.md # Decision logic for API development
β βββ skills/ # Development helper skill definitions (16 total)
β β βββ api-development/ # API endpoint design & decision logic
β β βββ handler/ # Business logic layer implementation
β β βββ repository-design/ # Data access layer design
β β βββ error-handling/ # Unified error handling patterns
β β βββ middleware/ # HTTP middleware implementation
β β βββ ef-core/ # EF Core optimization guide
β β βββ bdd-testing/ # BDD integration tests (Reqnroll/Gherkin)
β β βββ [9 other skills]
β βββ agents/ # AI Agent workflows (architecture review, feature development, etc.)
β
βββ dotnet-project-template/ # Main .NET project
β βββ src/be/ # Backend code
β β βββ JobBank1111.Infrastructure/ # Shared infrastructure (caching, logging, TraceContext)
β β βββ JobBank1111.Job.Contract/ # API contracts & auto-generated Client
β β βββ JobBank1111.Job.DB/ # EF Core DbContext & Entities
β β βββ JobBank1111.Job.WebAPI/ # API Controllers & middleware
β β βββ JobBank1111.Job.Test/ # Unit tests (Xunit)
β β βββ JobBank1111.Job.IntegrationTest/ # Integration tests (Reqnroll/BDD)
β β
β βββ doc/ # API specification documents
β β βββ openapi.yml # OpenAPI specification (Swagger)
β β
β βββ env/ # Environment configuration
β β βββ .template-config.json # Template configuration
β β βββ local.env # Local environment variables
β β
β βββ k8s/ # Kubernetes deployment configuration
β βββ docker-compose.yml # Local development environment (DB, Redis)
β βββ Taskfile.yml # Common tasks (build, test, deploy)
β
βββ CLAUDE.md # AI assistant behavior rules & plan management
βββ tree.md # Complete file listing
βββ .archive/ # Completed plan documents (for reference)
HTTP Request
β
[ Middleware Layer ] # Logging, authentication, TraceContext, error handling
β
[ Controller Layer ] # HTTP routing & request validation (MemberController.cs)
β
[ Handler Layer ] # Business logic (MemberHandler.cs)
β
[ Repository Layer ] # Data access abstraction (IMemberRepository)
β
[ EF Core DbContext ] # ORM implementation
β
[ Database ] # SQL Server / PostgreSQL
Choose the appropriate development approach based on your project stage (must choose one, do not mix):
| Approach | When to Use | Example File |
|---|---|---|
| API First | API specification is finalized, auto-generate Controller | MemberV1ControllerImpl.cs |
| Code First | Implement Controller directly without spec auto-generation | MemberController.cs |
π Detailed decision logic: see .claude/decision-framework.md
All API endpoints return a unified Result<T> structure:
{
"isSuccess": true,
"data": { ... },
"failure": null,
"traceId": "550e8400-e29b-41d4-a716-446655440000"
}- Benefits: Unified error handling, complete trace context, automatic logging
- Implementation: see /error-handling SKILL
Every request automatically gets a unique TraceId that flows through the entire call chain:
public class TraceContext
{
public string TraceId { get; set; } // Globally unique identifier
public string UserId { get; set; } // Current user
public DateTime RequestTime { get; set; }
}Facilitates log aggregation, performance analysis, and fault diagnosis.
Use C# record types and init properties to ensure objects cannot be modified after creation:
public record MemberResponse(
int Id,
string Name,
string Email
);All database and network operations use async/await:
public async Task<Result<MemberResponse>> GetMemberAsync(int id)
{
var member = await _repository.GetByIdAsync(id);
return member != null
? Result.Ok(new MemberResponse(member.Id, member.Name, member.Email))
: Result.Fail<MemberResponse>("Member not found");
}Suppose you need to implement a "Get Member List" endpoint:
-
Choose development approach (API First or Code First)
/api-development
-
Design data access layer
/repository-design
-
Implement business logic layer
/handler
-
Implement Controller
/handler # Also generates Controller reference -
Implement BDD tests
/bdd-testing
-
Verify completeness
dotnet test dotnet build
Consult corresponding documentation based on your task:
| Task | Related Document | Location |
|---|---|---|
| Understanding development workflow | SKILL usage guide | CLAUDE.md |
| Designing API endpoints | API development decision framework | .claude/decision-framework.md |
| Implementing Controller | Development rules & best practices | .claude/development-rules.md |
| Writing integration tests | BDD testing guide | .claude/skills/bdd-testing/SKILL.md |
| Caching design | Caching strategy decision | .claude/decision-framework.md#caching-strategy |
| Security checks | Security scanning tools | .claude/skills/security-* |
- CLAUDE.md β AI assistant behavior rules, plan management, advanced topics index
- .claude/development-rules.md β Development rules and best practices
- dotnet-project-template/docs/development/reqnroll-best-practices.md β BDD/Gherkin testing guide
# Development
dotnet build # Build the entire solution
dotnet run --project src/be/JobBank1111.Job.WebAPI # Start API server
dotnet watch run --project src/be/JobBank1111.Job.WebAPI # Hot reload mode
# Testing
dotnet test # Execute all tests (unit + integration)
dotnet test --filter FullyQualifiedName~Member # Run specific test
# Database migrations (using EF Core)
dotnet ef migrations add CreateMemberTable --project src/be/JobBank1111.Job.DB
dotnet ef database update --project src/be/JobBank1111.Job.DB
# Docker
docker-compose up -d # Start local development environment
docker-compose down # Stop development environment
docker-compose logs -f # View container logs- β Layered Architecture: Controller β Handler β Repository β DbContext
- β Immutable Objects: Use records and init properties
- β Async Operations: All I/O uses async/await
- β Result Pattern: Unified success/failure type
- β TraceContext: Every request carries a TraceId
- β BDD Tests: Integration tests use Gherkin/Reqnroll
- β Mixing API First and Code First approaches
- β Skipping async/await (synchronous I/O blocks threads)
- β Writing business logic directly in Controllers (violates layering)
- β Mocking databases in integration tests (use real Docker containers)
Swagger packages removed in favor of .NET 10 native OpenAPI (commit 15bcdf5)
- Removed: Swashbuckle.AspNetCore, Swashbuckle.AspNetCore.ReDoc, Scalar.AspNetCore
- Now using: Microsoft.AspNetCore.OpenApi (built-in .NET 10 support)
- Program.cs updated:
app.MapOpenApi()for native OpenAPI endpoint - Simpler, fewer dependencies, native framework integration
- Workflow questions: Consult CLAUDE.md and SKILL documentation
- Development decisions: Refer to .claude/decision-framework.md
- Technical issues: Check .claude/development-rules.md
Version: api.template v1.0
Last Updated: 2026-07-11
Purpose: For both human and AI Agent reading