Introduction
In this article, I will implement the facade design pattern with clean architecture for modern API Development.
Facade Pattern
The Facade pattern is a structural design pattern that provides a simplified interface to a set of interfaces in a subsystem, making it easier to use. It involves creating a unified interface that wraps a set of interfaces in a subsystem, thus simplifying the overall usage of the subsystem.
Clean Architecture
Clean Architecture is a software design philosophy introduced by Robert C. Martin (Uncle Bob). It emphasizes the separation of concerns and the organization of code into concentric circles or layers. The key idea is to separate the core business logic from the external concerns like the user interface, database, and frameworks. This separation promotes flexibility, maintainability, and testability.
Clean Architecture Layers
Presentation Layer (Web API)
- Controllers to handle HTTP requests.
- DTOs (Data Transfer Objects) for communication.
// Sardar Mudassar Ali Khan
// CarCompanyController.cs
[ApiController]
[Route("api/[controller]")]
public class CarCompanyController : ControllerBase
{
private readonly ICarCompanyFacade _carCompanyFacade;
public CarCompanyController(ICarCompanyFacade carCompanyFacade)
{
_carCompanyFacade = carCompanyFacade;
}
[HttpGet]
public IActionResult GetAll()
{
var carCompanies = _carCompanyFacade.GetAllCarCompanies();
return Ok(carCompanies);
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var carCompany = _carCompanyFacade.GetCarCompanyById(id);
return Ok(carCompany);
}
[HttpPost]
public IActionResult Create([FromBody] CarCompanyDto carCompanyDto)
{
var createdCompany = _carCompanyFacade.CreateCarCompany(carCompanyDto);
return CreatedAtAction(nameof(GetById), new { id = createdCompany.Id }, createdCompany);
}
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody] CarCompanyDto carCompanyDto)
{
_carCompanyFacade.UpdateCarCompany(id, carCompanyDto);
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_carCompanyFacade.DeleteCarCompany(id);
return NoContent();
}
}
Application Layer
- Interfaces for the Facade.
- Implementation of the Facade.
// Sardar Mudassar Ali Khan
// ICarCompanyFacade.cs
public interface ICarCompanyFacade
{
IEnumerable<CarCompanyDto> GetAllCarCompanies();
CarCompanyDto GetCarCompanyById(int id);
CarCompanyDto CreateCarCompany(CarCompanyDto carCompanyDto);
void UpdateCarCompany(int id, CarCompanyDto carCompanyDto);
void DeleteCarCompany(int id);
}
// Sardar Mudassar Ali Khan
// CarCompanyFacade.cs
public class CarCompanyFacade: ICarCompanyFacade
{
private readonly ICarCompanyService _carCompanyService;
public CarCompanyFacade(ICarCompanyService carCompanyService)
{
_carCompanyService = carCompanyService;
}
public IEnumerable<CarCompanyDto> GetAllCarCompanies()
{
try
{
var carCompanies = _carCompanyService.GetAllCarCompanies();
return carCompanies.Select(MapToDto);
}
catch (Exception ex)
{
throw new ApplicationException("Error occurred while fetching car companies.", ex);
}
}
public CarCompanyDto GetCarCompanyById(int id)
{
try
{
var carCompany = _carCompanyService.GetCarCompanyById(id);
return carCompany != null ? MapToDto(carCompany) : null;
}
catch (Exception ex)
{
throw new ApplicationException($"Error occurred while fetching car company with Id {id}.", ex);
}
}
public CarCompanyDto CreateCarCompany(CarCompanyDto carCompanyDto)
{
try
{
var newCompany = new CarCompany
{
Name = carCompanyDto.Name,
};
_carCompanyService.CreateCarCompany(newCompany);
return MapToDto(newCompany);
}
catch (Exception ex)
{
throw new ApplicationException("Error occurred while creating a new car company.", ex);
}
}
public void UpdateCarCompany(int id, CarCompanyDto carCompanyDto)
{
try
{
var existingCompany = _carCompanyService.GetCarCompanyById(id);
if (existingCompany != null)
{
existingCompany.Name = carCompanyDto.Name;
// Update other properties...
_carCompanyService.UpdateCarCompany(existingCompany);
}
else
{
throw new KeyNotFoundException($"Car company with Id {id} not found.");
}
}
catch (Exception ex)
{
throw new ApplicationException($"Error occurred while updating car company with Id {id}.", ex);
}
}
public void DeleteCarCompany(int id)
{
try
{
var existingCompany = _carCompanyService.GetCarCompanyById(id);
if (existingCompany != null)
{
_carCompanyService.DeleteCarCompany(existingCompany);
}
else
{
throw new KeyNotFoundException($"Car company with Id {id} not found.");
}
}
catch (Exception ex)
{
throw new ApplicationException($"Error occurred while deleting car company with Id {id}.", ex);
}
}
private CarCompanyDto MapToDto(CarCompany carCompany)
{
return new CarCompanyDto
{
Id = carCompany.Id,
Name = carCompany.Name,
};
}
}
Join the conversation! Your thoughts help the community grow.