This project is a boilerplate for building .NET API applications with various features such as authentication, rate limiting, CORS, and logging using Serilog.
Architecture & API
- Vertical Slicing Architecture
- Minimal API
- Swagger
- Health check endpoint
- Middlewares
- Entity Framework Core with SQLite
Authentication & Authorization
- Authentication using JWT Bearer tokens
- Authorization with role-based access control
- CORS policies for secure cross-origin requests
- Rate limiting to prevent API abuse
Validation & Logging
- FluentValidation
- Logging with Serilog
- Serilog with structured logging
Performance & Resiliency
- Response caching and compression
-  Performance
- Response Compression
- Response Caching
- GraphQL query optimization
- DataLoaders for efficient data fetching
 
GraphQL API with HotChocolate
- Professional architecture with clean separation
- Complete blog management domain (Blogs, Posts, Comments)
- DataLoaders for N+1 query prevention
- Real-time subscriptions with Redis
- Built-in GraphQL Playground and Schema explorer
- Query complexity analysis and rate limiting
- Field-level authorization support
- Comprehensive error handling
- Performance monitoring and observability
Deployment & CI/CD
- Docker
- Podman
- CloudFormation
- Github Action
Integrations
- Vault Integration
- MQ Integration
- .NET 9 SDK
- Keycloak for authentication
- 
Clone the repository: git clone https://github.com/FullstackCodingGuy/netapi-boilerplate.git cd netapi-boilerplate
- 
Install the required NuGet packages: dotnet restore 
- 
Update the appsettings.jsonandappsettings.Development.jsonfiles with your configuration.
- Build and run the application:
dotnet run or dotnet run --launch-profile "https"
1.1 Setting cert
dotnet dev-certs https -ep ${HOME}/.aspnet/https/dotnetapi-boilerplate.pfx -p mypassword234
dotnet dev-certs https --trust
Running with Docker
// To build the image
docker-compose build
// To run the container
docker-compose up
// To kill container
docker-compose down
- The application will be available at http://localhost:8000andhttps://localhost:8001(or the configured URL).
The application includes a health check endpoint to verify that the API is running. You can access it at:
GET /health
This will return a simple "Healthy" message.
This boilerplate includes a comprehensive GraphQL implementation using HotChocolate, designed with professional architecture patterns and enterprise-grade features.
- Clean Architecture: Vertical slicing with clear separation of concerns
- Domain-Driven Design: Blog management domain with Blogs, Posts, and Comments
- Repository Pattern: Abstracted data access with Entity Framework Core
- Service Layer: Business logic separation with comprehensive services
- Complete CRUD Operations: Full Create, Read, Update, Delete support
- Advanced Querying: Complex filtering, sorting, and pagination
- Real-time Subscriptions: Live updates using Redis as message broker
- Field-level Authorization: Granular security control
- Input Validation: Comprehensive data validation and sanitization
- DataLoaders: Automatic N+1 query prevention with batch loading
- Query Complexity Analysis: Protection against expensive queries
- Response Caching: Intelligent caching strategies
- Database Optimization: Efficient EF Core queries with projections
- JWT Authentication: Seamless integration with existing auth
- Role-based Authorization: Fine-grained access control
- Rate Limiting: GraphQL-specific rate limiting
- Comprehensive Logging: Structured logging with Serilog
- Error Handling: Professional error responses with detailed context
- Built-in GraphQL Playground: Interactive query interface at /graphql
- Schema Explorer: Full schema documentation and introspection
- Type Safety: Strongly typed resolvers and models
- Extensible Design: Easy to add new types and features
POST /graphql
- Primary endpoint for all GraphQL operations
- Supports queries, mutations, and subscriptions
- Built-in GraphQL Playground available in development
GET /graphql
- Interactive GraphQL IDE
- Schema exploration and documentation
- Query testing and validation
- Real-time subscription testing
query GetBlogsWithPosts {
  blogs {
    id
    name
    description
    posts {
      id
      title
      content
      author {
        name
        email
      }
      comments {
        id
        content
        author
      }
    }
  }
}mutation CreateBlog {
  createBlog(input: {
    name: "Tech Blog"
    description: "A blog about technology"
    author: "John Doe"
    tags: ["tech", "programming"]
  }) {
    blog {
      id
      name
      description
      author
      tags
      createdAt
    }
    errors {
      message
    }
  }
}subscription NewPosts {
  onPostCreated {
    id
    title
    content
    blog {
      name
    }
    author {
      name
    }
  }
}query SearchPosts {
  posts(
    where: {
      and: [
        { title: { contains: "GraphQL" } }
        { isPublished: { eq: true } }
        { createdAt: { gte: "2024-01-01" } }
      ]
    }
    order: [{ createdAt: DESC }]
    take: 10
  ) {
    id
    title
    content
    blog {
      name
    }
    commentCount
    viewCount
  }
}Features/GraphQL/
βββ Configuration/          # GraphQL server configuration
β   βββ GraphQLConfiguration.cs
βββ Models/                 # GraphQL types and DTOs
β   βββ BlogType.cs
β   βββ PostType.cs
β   βββ CommentType.cs
β   βββ AuthorType.cs
βββ Services/              # Business logic services
β   βββ IBlogService.cs
β   βββ BlogService.cs
β   βββ IPostService.cs
β   βββ PostService.cs
βββ Resolvers/             # GraphQL resolvers
β   βββ Query.cs           # Query operations
β   βββ Mutation.cs        # Mutation operations
β   βββ Subscription.cs    # Real-time subscriptions
β   βββ FieldResolvers.cs  # Field-level resolvers
βββ DataLoaders/           # Performance optimization
    βββ BlogDataLoaders.cs
    βββ PostDataLoaders.cs
Automatically batches and caches database queries to prevent N+1 problems:
- BlogByIdDataLoader: Efficient blog loading by ID
- PostsByBlogIdDataLoader: Batch loading of posts by blog
- CommentsByPostIdDataLoader: Efficient comment loading
Protects against expensive queries with configurable limits:
- Maximum query depth: 10 levels
- Maximum query complexity: 1000 points
- Field introspection limits in production
Multi-level caching for optimal performance:
- DataLoader-level caching (request scoped)
- Service-level caching for expensive operations
- Response caching for static data
- 
Start the application: dotnet run 
- 
Open GraphQL Playground: Navigate to http://localhost:8000/graphql
- 
Explore the Schema: Use the schema explorer to understand available types and operations 
- 
Try Sample Queries: Copy and paste the example queries above 
- 
Test Real-time Features: Open multiple browser tabs to test subscriptions 
GraphQL is configured in Features/GraphQL/Configuration/GraphQLConfiguration.cs with:
- HotChocolate Server: Latest version with all features enabled
- Entity Framework Integration: Automatic query translation
- Redis Subscriptions: Real-time capabilities
- Authentication Integration: JWT token validation
- Error Handling: Professional error responses
- Performance Monitoring: Query execution tracking
- Single Responsibility: Each resolver handles one concern
- Dependency Injection: All services properly registered
- Async/Await: Non-blocking operations throughout
- Error Boundaries: Comprehensive error handling
- Type Safety: Strong typing for all operations
- Documentation: Inline documentation for all types
- Testing Ready: Architecture supports unit and integration testing
This GraphQL implementation provides a solid foundation for building modern, efficient APIs with excellent developer experience and enterprise-grade performance.
Serilog is configured to log to the console and a file with daily rotation. You can customize the logging settings in the serilog.json file.
Example configuration in Program.cs:
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()   // Log to console
    .WriteTo.File("logs/api-log.txt", rollingInterval: RollingInterval.Day) // Log to a file (daily rotation)
    .Enrich.FromLogContext()
    .MinimumLevel.Information()
    .CreateLogger();
builder.Host.UseSerilog();Additional Configuration
- Authentication: Configure the JWT Bearer options in Program.cs to match your Keycloak settings.
- CORS: Update the CORS policies in Program.cs to match your frontend URLs.
- Rate Limiting: Adjust the rate limiting settings in Program.cs as needed.