前言
该系列前文提及到,要体现出资源的一个结构,那么如何体现出结构呢?比如说获取emproyee,应该写/api/companies/1/emproyees,这样可以体现其结构性。
那么这样改如何设置呢?
正文
[ApiController]
[Route("api/companies/{companyId}/employees")]
public class EmployeesController : ControllerBase
{
private readonly IMapper _mapper;
private readonly ICompanyRepository _companyRepository;
public EmployeesController(IMapper mapper, ICompanyRepository companyRepository)
{
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
_companyRepository = companyRepository ?? throw new ArgumentNullException(nameof(companyRepository));
}
[HttpGet]
public async Task<ActionResult<IEnumerable<EmployeeDto>>>
GetEmployeesForCompany(Guid companyId,
[FromQuery] EmployeeDtoParameters parameters){
if (!await _companyRepository.CompanyExistsAsync(companyId))
{
return NotFound();
}
var employees = await _companyRepository
.GetEmployeesAsync(companyId, parameters);
var employeeDtos = _mapper.Map<IEnumerable<EmployeeDto>>(employees);
return Ok(employeeDtos);
}
}
1.配置的路由为[Route("api/companies/{companyId}/employees")],这样companyId将会是一个变量,那么Guid companyId将会获取。
2.这里的逻辑是,employees 是从company的服务中中获取的,而不是单独的建立一个employees 服务。
3.同样值得注意的是获取得到是employees ,是一个集合,即使为空,这个集合也是存在的,所以不存在404这么一说,但是如果companyid 不存在那么这个就是404,因为可能不存在某个具体的公司。
这个时候如果返回404那么我们可以清晰的知道是公司不存在,而不是其他原因。
这个是获取一个集合的,那么获取某个单个员工呢。
和以前写的一样,如下:
[HttpGet("{employeeId}"]
public async Task<ActionResult<EmployeeDto>>
GetEmployeeForCompany(Guid companyId, Guid employeeId)
{
if (!await _companyRepository.CompanyExistsAsync(companyId))
{
return NotFound();
}
var employee = await _companyRepository.GetEmployeeAsync(companyId, employeeId);
if (employee == null)
{
return NotFound();
}
var employeeDto = _mapper.Map<EmployeeDto>(employee);
return Ok(employeeDto);
}
唯一值得注意的就是404,可能是公司不存在,也可能是员工不存在,这里可以返回404的时候去写上一些具体原因,但是也不必如此。
因为无论是公司不存在还是员工不存在,都是这个员工没有找到,直接提示相应的错误即可。还有一个原因,一般来说这种链接是自动生成的get请求,所以如果不存在人工选择的问题,所以如果404,前端的处理方式就是员工不存在,而不用去知道是是否公司不存在。