持久性无知和REST

时间:2016-06-11 17:22:12

标签: rest testing design-patterns persistence web-oriented-architecture

持久性无知(PI)是实现高效功能测试的关键指标。我认为它应该适用于一般的基础设施目的。但是,似乎很少在面向Web的架构(WOA)中遵循此指南,尤其是 REST API。由于REST似乎是一个以数据为中心的架构,我不明白为什么PI不以更流行的方式应用于WOA,以防止系统和昂贵的端到端测试。

是否有任何可以简化PI引入REST架构的架构或实践?根据您的经验,您是否尝试在REST架构中遵循PI原则?如果没有,为什么?

1 个答案:

答案 0 :(得分:3)

这都是层次和抽象的问题。无需REST端点即可了解数据在何处或如何持久保存。可以在运行时注入或交换持久性机制。终点应该只知道将API调用参数转换为下一层预期的任何内容(如果需要)。不可否认,许多REST实现使用持久性知识来加载终点,但这不是局限于RESTful API的问题。

SOLID中的一点D可用于将PI引入RESTful端点。

使用WebAPI示例,Controller(终点)只知道下一层的接口。出于测试目的,可以模拟该层以将测试与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);
    }
}