Author : MD TAREQ HASSAN | Updated : 2021/07/11
Path Base
- PathBase is used when multiple APIs are served under same domain
 - Each API will have it’s own PathBase
    
- Foo API: “
/api/foo” - Bar API: “
/api/bar” 
 - Foo API: “
 
Set PathBase in Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace API.Foo
{
    public class Startup
    {
        // ... ... ...
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // ... ... ...
			
            //
            // Path must start with "/" (otherwise, exception will be thrown)
            //			
            app.UsePathBase("/api/foo"); // ←―――――― base path for API
			
            app.UseRouting();
            // ... ... ...
        }
    }
}
Base Controller
- Base controller will contain:
    
- Common functionalities
 [ApiController]annotation: ControllerBaseinheritance
 - Base controller should not contain 
[Route]attribute (all controllers and actions should define route explicitly) 
FooBaseApiController.cs
using Microsoft.AspNetCore.Mvc;
namespace API.Foo.Controllers
{
    [ApiController]
    public abstract class FooBaseApiController : ControllerBase
    {
        //
        // Put common functionalities only
        //
        // Do not put route attribute
        //
    }
}
Attribute Routing
- All controllers and all actions should have explicit attribute route
 - Each API should have:
    
- A default controller and a default action (i.e. 
HomeController.Index()) - Default controller and default action should be defined by: 
[Route("~/")]and[HttpGet("~/")](see example below) 
 - A default controller and a default action (i.e. 
 - For controller
    
- Use SEO friendly URI
 - Example: 
[Route("employee-details")]→EmployeeDetailsController 
 - For controller action
    
- Also use SEO friendly URI
 - Example:
        
[HttpGet("personal-details")]→EmployeeDetailsController.GetPersonalDetails()[HttpGet("professional-details")]→EmployeeDetailsController.GetProfessionalDetails()
 
 - Each controller should have a default action with 
[HttpGet("")] 
TestController.cs
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
namespace API.Foo.Controllers
{
    [Route("test")] // ←―――――― explicit attribute route for controller
    public class TestController : FooBaseApiController
    {
        [HttpGet("")] // ←―――――― default action
        public string Index()
        {
            return $@"{{ 
			  ""scope"" : ""{ Assembly.GetAssembly(GetType()).GetName().Name}"", 
			  ""controller-name"" : ""{GetType().Name}"", 
			  ""method-name"" : ""{MethodBase.GetCurrentMethod().Name}"" 
			}}";
        }
        [HttpGet("xyz/{id:int?}")] // ←―――――― explicit attribute route for action
        public string Xyz(int? id)
        {
            return $@"{{ 
			  ""scope"" : ""{ Assembly.GetAssembly(GetType()).GetName().Name}"", 
			  ""controller-name"" : ""{GetType().Name}"", 
			  ""method-name"" : ""{MethodBase.GetCurrentMethod().Name}"", ""Id"" : ""{id}"" 
			}}";
        }
    }
}
Apply conventions to generate API docs
https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/conventions