持久性无知和 REST

Persistence Ignorance and REST

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

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

这都是层次和抽象的问题。 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);
    }
}