Вопрос по архитектуре WEB API
Я уже задавал подобный вопрос, но решил кое что добавить и подробнее описать. Я делаю свое WEB API, чтобы примерно понять и научиться технологии. Никаких требований от кого то нет, я сам все придумываю, поэтому что то может казаться не логичным. Я просто хочу научиться правильно строить архитектуру приложений. Теперь опишу само WEB API. Я решил что сделаю API по работе спорткомплекса. Есть сущности, и с ними манипуляции разные. Изначально я делал так: папка с самими сущностями (моделями), затем класс доступа к БД, папка репозиториев, которые как раз таки общаются с БД и производят манипуляции с данными. Репозитории отдельно под каждую используемую сущность. Затем я создал папку сервисов, в них так же интерфейсы, и классы их наследующие. Вот сервисы я уже делал так: "Допустим админ регистрирует тренера, значит я создаю сервис админа, в нем уже метод создания тренера, который использует репозиторий сущности Тренер". Правилен ли такой подход? Или под каждую сущность так же отдельный сервис? И нужны ли вообще сервисы? Контроллеры я создавал по такому же принципу, но мне объяснили, что нужно отдельно под каждую сущность свой контроллер, который использует уже сервисы. Кто нибудь объясните правильно ли я делал, или нет, и что нужно исправить. Вот примеры. Сущность Администрартор:
public class Administrator
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Surname { get; set; } = string.Empty;
public DateTime DateOfBirth { get; set; }
public string PhoneNumber { get; set; } = string.Empty;
public User User { get; set; }
public int UserId { get; set; }
}
Репозиторий администратора (класс):
public class AdministratorRepository : IAdministratorRepository
{
private readonly DataContext _context;
public AdministratorRepository(DataContext context)
{
_context = context;
}
public async Task<Administrator> Create(Administrator administrator)
{
_context.Administartors.Add(administrator);
await _context.SaveChangesAsync();
return administrator;
}
public async Task<Administrator?> Delete(int id)
{
var deleteAdministrator = await GetById(id);
if (deleteAdministrator == null)
return null;
_context.Administartors.Remove(deleteAdministrator);
await _context.SaveChangesAsync();
return deleteAdministrator;
}
public async Task<List<Administrator>> GetAll()
{
return await _context.Administartors.ToListAsync();
}
public async Task<Administrator?> GetById(int id)
{
return await _context.Administartors.FirstOrDefaultAsync(a => a.Id == id);
}
public async Task<Administrator?> Update(UpdateAdministratorDto request)
{
var admin = await GetById(request.Id);
if (admin == null)
return null;
admin.Name = request.Name;
admin.Surname = request.Surname;
admin.DateOfBirth = request.DateOfBirth;
admin.PhoneNumber = request.PhoneNumber;
await _context.SaveChangesAsync();
return admin;
}
}
Сервис админа (класс):
public class AdministratorService : IAdministratorService
{
private readonly IMapper _mapper;
private readonly IAdministratorRepository _adminRepository;
private readonly ICoachRepository _coachRepository;
private readonly ISectionRepository _sectionRepositroy;
private readonly ISubscriptionRepository _subscriptionRepository;
public AdministratorService
(
IMapper mapper,
IAdministratorRepository adminRepository,
ICoachRepository coachRepository,
ISectionRepository sectionRepository,
ISubscriptionRepository subscriptionRepository
)
{
_mapper = mapper;
_adminRepository = adminRepository;
_coachRepository = coachRepository;
_sectionRepositroy = sectionRepository;
_subscriptionRepository = subscriptionRepository;
}
public async Task<ResponseAPI<GetSubscriptionDto>> CreateSubscription(CreateSubscriptionDto request)
{
var response = new ResponseAPI<GetSubscriptionDto>();
try
{
var subscription = _mapper.Map<Subscription>(request);
await _subscriptionRepository.Create(subscription);
response.Data = _mapper.Map<GetSubscriptionDto>(subscription);
return response;
}
catch (Exception ex)
{
response.Data = null;
response.Success = false;
response.Message = ex.Message;
return response;
}
}
public async Task<ResponseAPI<List<GetSubscriptionDto>>> GetAllSubscriptions()
{
var response = new ResponseAPI<List<GetSubscriptionDto>>();
try
{
var subscriptionList = await _subscriptionRepository.GetAll();
response.Data = subscriptionList.Select(s => _mapper.Map<GetSubscriptionDto>(s)).ToList();
return response;
}
catch (Exception ex)
{
response.Data = null;
response.Success = false;
response.Message = ex.Message;
return response;
}
}
public async Task<ResponseAPI<GetAdministratorDto>> RegisterAdmin(RegisterAdministratorDto request)
{
var response = new ResponseAPI<GetAdministratorDto>();
try
{
var administrator = _mapper.Map<Administrator>(request);
var user = new User
{
Username = request.Username,
Password = request.Password,
Role = "Administrator"
};
administrator.User = user;
await _adminRepository.Create(administrator);
response.Data = _mapper.Map<GetAdministratorDto>(administrator);
return response;
}
catch (Exception ex)
{
response.Data = null;
response.Success = false;
response.Message = ex.Message;
return response;
}
}
public async Task<ResponseAPI<GetCoachDto>> RegisterCoach(RegisterCoachDto request)
{
var response = new ResponseAPI<GetCoachDto>();
try
{
var section = await _sectionRepositroy.GetByName(request.SectionName);
if (section == null)
throw new Exception("There is no section with the given name");
var coach = _mapper.Map<Coach>(request);
var user = new User
{
Username = request.Username,
Password = request.Password,
Role = "Coach"
};
coach.User = user;
coach.Section = section;
await _coachRepository.Create(coach);
response.Data = _mapper.Map<GetCoachDto>(coach);
return response;
}
catch (Exception ex)
{
response.Data = null;
response.Success = false;
response.Message = ex.Message;
return response;
}
}
}
Контроллер администратора:
public class AdministratorController : ControllerBase
{
private readonly IAdministratorService _service;
public AdministratorController(IAdministratorService service)
{
_service = service;
}
[HttpPost("register/administrator")]
[Authorize(Roles = "Administrator")]
public async Task<ActionResult<ResponseAPI<GetAdministratorDto>>> RegisterAdmin(RegisterAdministratorDto request)
{
var response = await _service.RegisterAdmin(request);
if (response.Data == null)
return BadRequest(response);
return Ok(response);
}
[HttpPost("register/coach")]
[Authorize(Roles = "Administrator")]
public async Task<ActionResult<ResponseAPI<GetCoachDto>>> RegisterCoach(RegisterCoachDto request)
{
var response = await _service.RegisterCoach(request);
if (response.Data == null)
return BadRequest(response);
return Ok(response);
}
[HttpGet("subscription")]
[Authorize(Roles = "Administrator")]
public async Task<ActionResult<ResponseAPI<List<GetSubscriptionDto>>>> GetAllSubscriptions()
{
var response = await _service.GetAllSubscriptions();
if (response.Data == null)
return BadRequest(response);
return Ok(response);
}
[HttpPost("subscription")]
[Authorize(Roles = "Administrator")]
public async Task<ActionResult<ResponseAPI<GetSubscriptionDto>>> CreateSubscription(CreateSubscriptionDto request)
{
var response = await _service.CreateSubscription(request);
if (response.Data == null)
return BadRequest(response);
return Ok(response);
}
}