持久性无知(PI)是实现有效功能测试的关键指南。我相信它应该总体上适用于基础设施目的。但是,似乎该指南在面向Web的体系结构(WOA)中很少遵循,尤其是在REST API中。由于REST似乎是以数据为中心的体系结构,因此我不明白为什么PI不能以更流行的方式应用于WOA,以防止进行系统且昂贵的端到端测试。
是否有某种架构或实践可以简化PI在REST架构中的引入?根据您的经验,您是否尝试在REST体系结构中遵循PI原则?如果没有,为什么?
最佳答案
这都是分层和抽象的问题。 REST端点无需了解任何有关数据在哪里或如何持久存储的知识。持久性机制可以在运行时注入或换出。端点应该只知道足够的知识,才能将API调用参数转换为下一层所期望的内容(如果需要)。诚然,许多REST实现都使用持久性知识来加载端点,但这并不是仅限于RESTful API的问题。
SOLID中的少量D可用于将PI引入RESTful端点。
使用WebAPI示例,控制器(端点)仅了解下一层的接口。出于测试目的,可以模拟该层以将测试隔离到API本身。如果需要更复杂的逻辑或访问多个存储库,则下一层可以是持久层或服务层。
public class ValuesController : ApiController
{
//controller only knows about the interface to the next layer down
private readonly IServiceOrRepositoryLayer _serviceOrRepo;
//persistence or service layer injected into the constructor
//useful for testing
//could also inject a factory if more flexibility needed at runtime
public ValuesController(IServiceOrRepositoryLayer serviceOrRepo)
{
_serviceOrRepo = serviceOrRepo;
}
// GET api/values
public IEnumerable<SomePOCO> Get()
{
return _serviceOrRepo.ListAll();
}
// GET api/values/5
public SomePOCO Get(int id)
{
return _serviceOrRepo.Get(id);
}
// POST api/values
public void Post(SomePOCO value)
{
//can either pass the value directly or transform it here
//to what the next layer needs
_serviceOrRepo.Create(value);
}
// PUT api/values/5
public void Put(int id, SomePOCO value)
{
_serviceOrRepo.Update(value, id);
}
// DELETE api/values/5
public void Delete(int id)
{
_serviceOrRepo.Delete(id);
}
}