我正在研究REST-API,并遇到了一个架构问题。
模型“book”表示一本具有属性和基于CRUD函数的书籍。它通过读取函数从数据库加载自己。
但是,如果我想把所有的书都放在数据库里呢?当前的图书模型没有涵盖这个用例。
我尝试过几种方法:
1.)第二种模式叫做“书籍”。它有一个read函数,它返回图书对象的列表。
2.)模型'Book‘本身有一个加载所有书籍的readAll函数。
3.)模型'Book‘是没有功能的,它只具有属性。相反,“BookStorage”类加载数据并填充一个/多个模型。
我对其中任何一种方法都不满意。对于这个场景有最佳实践吗?
发布于 2015-05-05 15:17:10
1.)第二种模式叫做“书籍”。它有一个read函数,它返回图书对象的列表。
这是可以的,但是这个项目的用户和未来的开发人员可能不清楚你有书和书这一事实。因此,一定要记录API,并对代码进行注释。此外,您确实需要考虑输入筛选器来限制结果,或者至少需要一个页面结果的方法。谷歌曾经估计有1.3亿本书,所以你想一次把它们都拿到吗?
例如服务器/图书/?skipRecords=0&limit=100
2.)模型'Book‘本身有一个加载所有书籍的readAll函数。
这并不理想,因为它违反了单一责任原则。大多数情况下,在面向对象的情况下,一个单一的图书实体能够列出所有的同级实体是没有什么意义的。
服务器/霍比特人/readAll..。真恶心。
3.)模型'Book‘是没有功能的,它只具有属性。相反,“BookStorage”类加载数据并填充一个/多个模型。如果您可以通过API公开这些函数扩展,那么这也是一个很好的解决方案。这一切都取决于文件。
也许它最终会变成这样
例如:
SERVER/BookStorage/GetAllBooks?skipRecords=0&limit=100
服务器/图书存储/GetBook?title=TheHobbit
发布于 2015-05-05 16:25:50
3.)模型'Book‘是没有功能的,它只具有属性。相反,“BookStorage”类加载数据并填充一个/多个模型。
这种方法类似于存储库模式,并且非常常见。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)的内容。
模型不应该加载自身,因为它会违反单一责任原则。
发布于 2015-05-05 21:39:59
在设计RESTful when服务时,一个很好的资源是Martin的文章Richardson成熟度模型。
为了总结一下您的book案例:
POST /book创建一本书PUT /book更新书籍GET /book?author=Shakespeare&year=1602&someOtherParam=someValue查找书籍GET /book/:id检索特定书籍的详细信息DELETE /book/:id删除某本书另外,您可能希望遵循哈特奥原则,因此您需要将书籍的所有相关链接包含到links属性中,这样当您的API客户端想要添加/编辑/查找/删除一本书时,就不需要构建他们自己的链接了。
虽然乍一看很简单,但是设计一个好的RESTful they服务并不容易,但是HATEOAS有帮助,因为服务器端的url模式更改不会影响客户端,因为它们不会硬编码CRUD操作所需的URL。您所需要做的就是提供一个起点,例如,可以在其中发现所有内容的基url,并且客户端可以从那里开始浏览您的All服务。
https://stackoverflow.com/questions/30056524
复制相似问题