Important Notice
While using ChatGPT, don't copy-paste exact content. Read carefully and make necessary changes.
1. Introduction
This document outlines coding standards and best practices for .NET Core API development, ensuring consistency, maintainability, and high performance. It serves as a guideline for Sioniq developers working on API projects.
2. Purpose
Establishing consistent coding practices improves code readability, reliability, and scalability, and enhances collaboration across the development team.
3. Project Structure
root │ ├── .vscode/ # VS Code configuration files (optional) │ └── launch.json # Debug configurations │ └── tasks.json # Task configurations │ ├── src/ │ ├── SioniqAIAPI/ # Main API project │ │ ├── Controllers/ # Controllers for handling API requests │ │ │ ├── Admin/ # Controllers related to Admin module │ │ │ ├── Master/ # Controllers related to Master module │ │ │ │ ├── CountryController.cs # Controller for country-related endpoints │ │ │ │ └── BlogPostsController.cs # Controller for blog posts-related endpoints │ │ │ └── Inventory/ # Controllers related to Inventory module │ │ │ └── PurchaseController.cs # Controller for purchase-related endpoints │ │ ├── Utilities/ # Utility classes and helper functions │ │ │ └── SampleUtility.cs # Example utility class │ │ ├── XMLFiles/ # XML configuration or data files │ │ │ └── sample-config.xml # Example XML file │ │ ├── Models/ # Data models for binding request/response payloads │ │ │ ├── Domain/ # Domain models representing core entities │ │ │ │ ├── Admin/ # Domain models related to Admin module │ │ │ │ ├── Master/ # Domain models related to Master module │ │ │ │ │ ├── Country/ # Domain models related to Country │ │ │ │ │ │ └── mstCountry.cs # Updated Country entity model │ │ │ │ │ ├── State/ # Domain models related to State │ │ │ │ │ └── Bank/ # Domain models related to Bank │ │ │ │ │ └── mstBank.cs # Updated Bank entity model │ │ │ │ ├── Inventory/ # Domain models related to Inventory module │ │ │ │ │ └── Order/ # New Order folder under Inventory │ │ │ │ │ ├── invOrderHDR.cs # Order Header model │ │ │ │ │ ├── invOrderHDR_History.cs # Order Header History model │ │ │ │ │ ├── invOrderVRL.cs # Order Variable model │ │ │ │ │ ├── invOrderVRL_History.cs # Order Variable History model │ │ │ │ │ ├── invOrderItemsDTL.cs # Order Items Detail model │ │ │ │ │ ├── invOrderItemsDTL_History.cs # Order Items Detail History model │ │ │ │ │ ├── invOrderItemsVRL.cs # Order Items Variable model │ │ │ │ │ └── invOrderItemsVRL_History.cs # Order Items Variable History model │ │ │ │ └── POS/ # Domain models related to POS module │ │ │ └── DTO/ # Data Transfer Objects for request and response payloads │ │ │ ├── Admin/ # DTOs related to Admin module │ │ │ ├── Master/ # DTOs related to Master module │ │ │ │ ├── Country/ # DTOs related to Country │ │ │ │ │ ├── AddmstCountryDto.cs # Updated DTO for adding country data │ │ │ │ │ ├── UpdatemstCountryDto.cs # Updated DTO for updating country data │ │ │ │ │ └── GetmstCountryDto.cs # Updated DTO for retrieving country data │ │ │ │ ├── State/ # DTOs related to State │ │ │ │ └── Bank/ # DTOs related to Bank │ │ │ │ ├── AddmstBankDto.cs # Updated DTO for adding bank data │ │ │ │ ├── UpdatemstBankDto.cs # Updated DTO for updating bank data │ │ │ │ └── GetmstBankDto.cs # Updated DTO for retrieving bank data │ │ │ ├── Inventory/ # DTOs related to Inventory module │ │ │ │ └── Order/ # Order folder under Inventory DTOs │ │ │ │ ├── AddinvOrderHDRDto.cs # DTO for adding Order Header data │ │ │ │ ├── AddinvOrderVRLDto.cs # DTO for adding Order Variable data │ │ │ │ ├── AddinvOrderItemsDTLDto.cs # DTO for adding Order Items Detail data │ │ │ │ ├── AddinvOrderItemsVRLDto.cs # DTO for adding Order Items Variable data │ │ │ │ ├── GetinvOrderHDRDto.cs # DTO for retrieving Order Header data │ │ │ │ ├── GetinvOrderVRLDto.cs # DTO for retrieving Order Variable data │ │ │ │ ├── GetinvOrderItemsDTLDto.cs # DTO for retrieving Order Items Detail data │ │ │ │ ├── GetinvOrderItemsVRLDto.cs # DTO for retrieving Order Items Variable data │ │ │ │ ├── UpdateinvOrderHDRDto.cs # DTO for updating Order Header data │ │ │ │ ├── UpdateinvOrderVRLDto.cs # DTO for updating Order Variable data │ │ │ │ ├── UpdateinvOrderItemsDTLDto.cs # DTO for updating Order Items Detail data │ │ │ │ └── UpdateinvOrderItemsVRLDto.cs # DTO for updating Order Items Variable data │ │ │ └── POS/ # DTOs related to POS module │ │ ├── Data/ # Database context and related classes │ │ │ ├── ApplicationDbContext.cs # Main application database context │ │ │ ├── Factories/ # Factory classes for data creation and setup │ │ │ │ └── SampleFactory.cs # Example factory for creating sample data │ │ ├── Migrations/ # Database migration files (if using Entity Framework Core) │ │ ├── Repositories/ # Repository classes for data access abstraction │ │ │ ├── Implementations/ # Implementation classes for repositories │ │ │ │ ├── Admin/ # Implementations related to Admin module │ │ │ │ ├── Master/ # Implementations related to Master module │ │ │ │ │ ├── CountryRepository.cs # Implementation of country repository │ │ │ │ │ └── BankRepository.cs # Implementation of bank repository │ │ │ │ ├── Inventory/ # Implementations related to Inventory module │ │ │ │ │ └── InventoryRepository.cs # Implementation of inventory repository │ │ │ │ └── POS/ # Implementations related to POS module │ │ │ └── Interface/ # Interfaces for repositories │ │ │ ├── Admin/ # Interfaces related to Admin module │ │ │ ├── Master/ # Interfaces related to Master module │ │ │ │ ├── iCountryRepository.cs # Interface for country repository │ │ │ │ └── iBankRepository.cs # Interface for bank repository │ │ │ ├── Inventory/ # Interfaces related to Inventory module │ │ │ │ └── iInventoryRepository.cs # Interface for inventory repository │ │ │ └── POS/ # Interfaces related to POS module │ │ ├── Swagger/ # Swagger configuration and customizations │ │ ├── Startup.cs # Application startup configuration │ │ └── Program.cs # Main entry point of the application │ ├── .gitignore # Git ignore file ├── README.md # Project documentation ├── LICENSE # Project license ├── docker-compose.yml # Docker compose file for container orchestration └── SioniqAIAPI.sln # Solution file
4. Namespace Usage Guide
This section provides a guide on how to structure and use namespaces across different components of the SioniqAIAPI project. Proper namespace usage ensures consistency, reduces conflicts, and improves code organization.
4.1. Controllers
The SioniqAIAPI.Controllers namespace is used to define all the controllers in the application. Controllers handle incoming HTTP requests, execute business logic, and return responses.
namespace SioniqAIAPI.Controllers
{
// Example Controller for handling API requests
public class ExampleController : ControllerBase
{
// Action methods for handling specific routes
}
}
4.2. Data
The SioniqAIAPI.Data namespace includes classes responsible for database interaction, data contexts, and data management. It can also include factories or services that interact with the database.
namespace SioniqAIAPI.Data
{
public class ApplicationDbContext : DbContext
{
// DB sets and configurations
}
}
4.3. Migrations
The SioniqAIAPI.Migrations namespace contains the migration classes used to manage changes to the database schema over time, using Entity Framework or other ORM tools.
namespace SioniqAIAPI.Migrations
{
public class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// Migration logic
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// Revert migration logic
}
}
}
4.4. Domain Models
The SioniqAIAPI.Models.Domain namespace includes classes that define the core entities of the application. These models typically correspond to database tables and represent the business logic.
namespace SioniqAIAPI.Models.Domain
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
// Other properties
}
}
4.5. Data Transfer Objects (DTO)
The SioniqAIAPI.Models.DTO namespace contains Data Transfer Objects. DTOs are used to transfer data between layers of the application or across service boundaries, typically for API responses or requests.
namespace SioniqAIAPI.Models.DTO
{
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; }
// Other properties
}
}
4.6. Repository Implementations
The SioniqAIAPI.Repositories.Implementations namespace includes concrete implementations of the repository interfaces. These classes handle the actual data fetching, saving, and other database-related operations.
namespace SioniqAIAPI.Repositories.Implementations
{
public class ProductRepository : IProductRepository
{
private readonly ApplicationDbContext _context;
public ProductRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task GetProductById(int id)
{
return await _context.Products.FindAsync(id);
}
}
}
4.7. Repository Interfaces
The SioniqAIAPI.Repositories.Interface namespace contains the interfaces for the repositories. These interfaces define the contract for repository operations, which ensures separation of concerns and testability.
namespace SioniqAIAPI.Repositories.Interface
{
public interface IProductRepository
{
Task GetProductById(int id);
// Other repository methods
}
}
4.8. Best Practices
- Namespaces should reflect the functionality and purpose of the class within the application.
- Follow the principle of separation of concerns, ensuring that controllers only handle request processing, and repositories focus on data access.
5. .NET Core API Controllers Coding Standards & Best Practices
This section outlines the coding standards and best practices for writing controllers in a .NET Core API application. These guidelines aim to ensure clarity, maintainability, and consistency across the project's controllers.
5.1. Controller Naming Convention
Controllers should be named clearly and consistently to reflect the resource or functionality they represent. The name of the controller should end with "Controller" to follow convention.
Example: ProductController, OrderController, CustomerController.
namespace SioniqAIAPI.Controllers
{
public class ProductController : ControllerBase
{
// Controller actions
}
}
5.2. Controller Inheritance
All controllers should inherit from ControllerBase to provide access to common API functionality such as model binding, request processing, and response handling.
public class ProductController : ControllerBase
{
// Controller logic
}
5.3. Single Responsibility Principle
Each controller should follow the Single Responsibility Principle (SRP). This means that each controller should manage one set of related actions or a single resource. Avoid making a controller handle multiple, unrelated resources.
public class ProductController : ControllerBase
{
private readonly IProductRepository _productRepository;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
// Product-related actions
}
5.4. Dependency Injection
Controllers should rely on dependency injection (DI) for accessing services, repositories, or other components. This promotes loose coupling and enhances testability.
public class ProductController : ControllerBase
{
private readonly IProductService _productService;
public ProductController(IProductService productService)
{
_productService = productService;
}
// Controller actions
}
5.5. RESTful API Endpoints
Controllers should follow RESTful principles. Actions within controllers should map to HTTP methods (GET, POST, PUT, DELETE) and should operate on resources represented by models.
- GET Used to retrieve information from the server without modifying it.
- POST Used to create a new resource on the server.
- PUT Used to update an existing resource on the server.
- DELETE Used to delete a resource on the server.
- PATCH Used to partially update a resource on the server. Often used with JSON Patch operations.
- OPTIONS Retrieves the available communication options for a resource, typically for CORS support.
- HEAD Similar to GET but retrieves only headers and status without the response body, often for metadata or existence checks.
HTTP methods Naming Convention
| HTTP Methods | HTTP Verbs | Endpoint Prefix | EndPoint Name | Remarks |
|---|---|---|---|---|
| GET | [HttpGet] |
Get |
GetCategories | built-in |
| POST | [HttpPost] |
Create |
CreateCategories | built-in |
| PUT | [HttpPut] |
Update |
UpdateCategories | built-in |
| DELETE | [HttpDelete] |
Delete |
DeleteCategories | built-in |
| PATCH | [HttpPatch] |
|
|
built-in |
| OPTIONS | [HttpOptions] |
|
|
built-in |
| HEAD | [HttpHead] |
|
|
built-in |
| TRACE | |
|
|
Custom Middleware |
| CONNECT | |
|
|
Custom Middleware |
| SYNC | |
|
|
Custom Middleware |
public class ProductController : ControllerBase
{
[HttpGet("{id}")]
public ActionResult GetProduct(int id)
{
var product = _productRepository.GetById(id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
[HttpPost]
public ActionResult CreateProduct(ProductDto productDto)
{
var createdProduct = _productService.Create(productDto);
return CreatedAtAction(nameof(GetProduct), new { id = createdProduct.Id }, createdProduct);
}
}
5.6. Consistent Response Types
Always return HTTP status codes along with your responses. Use the ActionResult type, which allows for returning various HTTP status codes and responses in a consistent manner.
public ActionResult GetProduct(int id)
{
var product = _productRepository.GetById(id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
5.7. Validation and Error Handling
Always validate inputs, either manually or using model validation attributes. Return proper error messages and HTTP status codes when validation fails.
public ActionResult CreateProduct(ProductDto productDto)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var createdProduct = _productService.Create(productDto);
return CreatedAtAction(nameof(GetProduct), new { id = createdProduct.Id }, createdProduct);
}
5.8. Use Asynchronous Programming
For I/O-bound operations, always use asynchronous programming. This helps improve the scalability and responsiveness of your API.
public async Task> GetProduct(int id)
{
var product = await _productRepository.GetByIdAsync(id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
5.9. Use HTTP Status Codes Appropriately
Use the correct HTTP status codes for different scenarios:
200 OKfor successful GET requests.201 Createdfor successful POST requests.400 Bad Requestfor invalid inputs.404 Not Foundwhen the resource is not found.500 Internal Server Errorfor server-side errors.
5.10. Best Practices Summary
- Follow the RESTful conventions for all API actions.
- Ensure all controllers have a single responsibility.
- Always handle exceptions and return appropriate HTTP status codes.
- Use asynchronous methods for I/O-bound operations.
- Apply consistent naming conventions for controller actions and parameters.
- Document your API with tools like Swagger.
- Ensure security by validating inputs and using secure practices.
6. .NET Core API Domain Coding Standards
This section outlines the coding standards and best practices for the **Domain Layer** in a .NET Core API application. The Domain Layer represents the core business logic of the application and should be designed for maintainability, scalability, and testability.
6.1. Domain Layer Overview
The Domain Layer in a .NET Core API represents the application's core business logic. It should contain the domain models, business rules, and interactions that define the business operations. The Domain layer is typically free of infrastructure concerns such as database access or external services.
6.2. Domain Model Naming Convention
Domain models should represent business concepts and be named clearly to reflect their purpose. Models should follow singular naming conventions and use proper casing. Avoid using technical terms like "DTO" or "ViewModel" in domain model names.
| Module | Table Type | Row Table Name | Actual Table Name | Domain Model | Verticle Table Name | Domain Model |
|---|---|---|---|---|---|---|
| Inventory | (Parent) | Order | invOrderHDR |
invOrderHDR.cs |
invOrderHDR_History |
invOrderHDR_History.cs |
| Inventory | (Child) | OrderItems | invOrderItemsDTL |
invOrderItemsDTL.cs |
invOrderItemsDTL_History |
invOrderItemsDTL_History.cs |
| Admin | (Parent) | Invoice | admInvoiceHDR |
admInvoiceHDR.cs |
admInvoiceHDR_History |
admInvoiceHDR_History.cs |
| Admin | (Child) | InvoiceItems | admInvoiceITEMSDTL |
admInvoiceITEMSDTL.cs |
admInvoiceITEMSDTL_History |
admInvoiceITEMSDTL_History.cs |
| Admin | (No Child Table) | Country | admCountry |
admCountry.cs |
admCountry_History |
admCountry_History.cs |
| Module | Table Type | Row Table Name | Actual Table Name | Domain Model | Verticle Table Name | Domain Model |
|---|---|---|---|---|---|---|
| Inventory | (Parent) | Order | invOrderVRL |
invOrderVRL.cs |
invOrderVRL_History |
invOrderVRL_History.cs |
| Inventory | (Child) | OrderItems | invOrderItemsVRL |
invOrderItemsVRL.cs |
invOrderItemsVRL_History |
invOrderItemsVRL_History.cs |
| Admin | (Parent) | Invoice | admInvoiceVRL |
admInvoiceVRL.cs |
admInvoiceVRL_History |
admInvoiceVRL_History.cs |
| Admin | (Child) | InvoiceItems | admInvoiceItemsVRL |
admInvoiceItemsVRL.cs |
admInvoiceItemsVRL_History |
admInvoiceItemsVRL_History.cs |
| Admin | (No Child Table) | Country | admCountryVRL |
admCountryVRL.cs |
admCountryVRL_History |
admCountryVRL_History.cs |
7. .NET Core API DTO Coding Standards
| Module | Row Table Name | Actual Table Name | Domain Model | Add DTO | Update DTO | Get DTO |
|---|---|---|---|---|---|---|
| Inventory(Parent) | Order | invOrderHDR |
invOrderHDRDto.cs |
AddinvOrderHDRDto.cs |
UpdateinvOrderHDRDto.cs |
GetinvOrderHDRDto.cs |
| Inventory(Parent) | Order | invOrderVRL |
invOrderVRLDto.cs |
AddinvOrderVRLDto.cs |
UpdateinvOrderVRLDto.cs |
GetinvOrderVRLDto.cs |
| Inventory(Child) | OrderItems | invOrderItemsDTL |
invOrderItemsDTLDto.cs |
AddinvOrderItemsDTLDto.cs |
UpdateinvOrderItemsDTLDto.cs |
GetinvOrderItemsDTLDto.cs |
| Inventory(Child) | OrderItems | invOrderItemsVRL |
invOrderItemsVRLDto.cs |
AddinvOrderItemsVRLDto.cs |
UpdateinvOrderItemsVRLDto.cs |
GetinvOrderItemsVRLDto.cs |
| Admin(Parent) | Invoice | admInvoiceHDR |
admInvoiceHDRDto.cs |
AddadmInvoiceHDRDto.cs |
UpdateadmInvoiceHDRDto.cs |
GetadmInvoiceHDRDto.cs |
| Admin(Parent) | Invoice | admInvoiceVRL |
admInvoiceVRLDto.cs |
AddadmInvoiceVRLDto.cs |
UpdateadmInvoiceVRLDto.cs |
GetadmInvoiceVRLDto.cs |
| Admin(Child) | InvoiceItems | admInvoiceITEMSDTL |
admInvoiceITEMSDTLDto.cs |
AddadmInvoiceITEMSDTLDto.cs |
UpdateadmInvoiceITEMSDTLDto.cs |
GetadmInvoiceITEMSDTLDto.cs |
| Admin(Child) | InvoiceItems | admInvoiceItemsVRL |
admInvoiceItemsVRLDto.cs |
AddadmInvoiceItemsVRLDto.cs |
UpdateadmInvoiceItemsVRLDto.cs |
GetadmInvoiceItemsVRLDto.cs |
| Admin(No Child Table) | Country | admCountry |
admCountryDto.cs |
AddadmCountryDto.cs |
UpdateadmCountryDto.cs |
GetadmCountryDto.cs |
| Admin(No Child Table) | Country | admCountryVRL |
admCountryVRLDto.cs |
AddadmCountryVRLDto.cs |
UpdateadmCountryVRLDto.cs |
GetadmCountryVRLDto.cs |
8. Interface & Implementation Standards
| Repository Purpose | Interface Naming Convention | Implementation Naming Convention |
|---|---|---|
| Country Repository | iCountryRepository |
CountryRepository |
| Bank Repository | iBankRepository |
BankRepository |
| Inventory Repository | iInventoryRepository |
InventoryRepository |
| POS Repository | iPOSRepository |
POSRepository |
| User Repository | iUserRepository |
UserRepository |
| Product Repository | iProductRepository |
ProductRepository |
| Order Repository | iOrderRepository |
OrderRepository |
| Customer Repository | iCustomerRepository |
CustomerRepository |
| Transaction Repository | iTransactionRepository |
TransactionRepository |