REST-API模型的最佳实践

时间:2015-05-05 14:58:32

标签: rest design-patterns model-view-controller model mvp

我正在研究REST-API并遇到了架构问题。

该模型' Book'表示具有属性和基于CRUD的函数的单本书。它通过读取函数从数据库加载自身。

但是,如果我想获取数据库中的所有书籍怎么办?目前的书籍模型不包括这个用例。

我尝试了几种方法:

1。)第二个名为“书籍”的模型。它有一个read函数,它返回一个book对象列表。

2。)模型' Book'本身有一个readAll函数,可以加载所有书籍。

3。)模型' Book'是无功能的,只有属性。取而代之的是BookStorage' class加载数据并填充一个/多个模型。

我对这些方法都不满意。这种情况有最佳实践吗?

4 个答案:

答案 0 :(得分:2)

  

1。)第二个模型叫做“书籍”。它有一个read函数,它返回一个book对象列表。

这没关系,但项目的用户和未来的开发人员可能不清楚你有Book和Books这两个事实。所以一定要记录API,并注释代码。此外,您需要考虑输入过滤器来限制结果,或者至少考虑一种页面结果的方法。谷歌曾经估计有1.3亿本书,所以你想立刻获得所有这些书?

e.g。 SERVER /书籍/ skipRecords = 0&安培;限= 100

  

2。)模型'Book'本身有一个readAll函数,可以加载所有书籍。

这并不理想,因为它违反了单一责任主体。大多数情况下,在OO情况下,只有一个图书实体能够列出其所有兄弟实体,这一点并没有多大意义。

e.g。 SERVER / TheHobbit / readAll .... yuck。

  

3。)“Book”模型不起作用,只有属性。相反,'BookStorage'类加载数据并填充一个/多个   楷模。   如果您可以通过API公开这些功能扩展,那么这也是一个很好的解决方案。这一切都归结为文档。

也许最终看起来像这样

e.g。

SERVER / BookStorage / GetAllBooks skipRecords = 0&安培;限= 100

SERVER / BookStorage / GetBook?标题= TheHobbit

答案 1 :(得分:0)

  

3。)模型' Book'是无功能的,只有属性。取而代之的是BookStorage' class加载数据并填充一个/多个模型。

这种方法类似于Repository Pattern,非常常见。 BookStorage是一个BookRepository,其界面如下:

public interface IBookRepository
{
    Book GetById(int id);
    IEnumerable<Book> GetAll();
    // Other methods for creating, updating and deleting books.
}

在您的控制器中,您将拥有:

public class BooksController: ApiController
{
    private readonly IBookRepository _bookRepository;

    public BooksController(IBookRepository bookRepository)
    {
        _bookRepository = bookRepository;
    }

    [Route("api/books/{id}")]
    public IHttpActionResult Get(int id)
    {
        var book = _bookRepository.GetById(id);

        // ...
    }

    [Route("api/books")]
    public IHttpActionResult Get()
    {
        var books = _bookRepository.GetAll();

        // ...
    }
}

如果您想要分页,可以添加Get(int page = 0)之类的过滤器,然后根据您的页面大小,使用类似bookRepository.GetAll().Skip(PAGE_SIZE * page).Take(PAGE_SIZE)的内容。

模型不应加载自身,因为它会违反Single responsibility principle

答案 2 :(得分:0)

设计RESTful Web服务时的一个很好的资源是Martin Fowler的文章Richardson Maturity Model

总结您的book案例:

  • 使用POST /book创建图书
  • 使用PUT /book更新图书
  • 使用GET /book?author=Shakespeare&year=1602&someOtherParam=someValue查找图书
  • 使用GET /book/:id检索特定图书的详细信息
  • 使用DELETE /book/:id删除某本书

此外,您可能希望遵循HATEOAS原则,因此您需要将图书的所有相关链接都包含在links属性中,以便您的API客户端无需构建当他们想要添加/编辑/查找/删除图书时,他们自己的链接。

虽然初看起来很简单,但设计一个好的RESTful Web服务并不容易,但HATEOAS会有所帮助,因为服务器端的url架构更改不会影响客户端,因为它们不会对{{1}所需的URL进行硬编码操作。您需要做的就是提供一个起点,例如:一个基本网址,可以发现所有内容,客户可以从那里开始浏览您的网络服务。

答案 3 :(得分:0)

请阅读此处的CRUD Operations部分。您将在设计REST API时找到要遵循的REST最佳实践