简体   繁体   English

RESTful API的效率

[英]Efficiency of RESTful APIs

I'm currently creating an application (let's say, notes app, for instance - webapplication + mobile app). 我当前正在创建一个应用程序(例如,Notes应用程序-Web应用程序+移动应用程序)。 I wanted to use RESTful API here, so I read a lot about this topic and I found out there's a lot of ambiguity over there. 我想在这里使用RESTful API,所以我阅读了很多有关此主题的内容,发现那里存在很多歧义。

So let's start at the beginning. 因此,让我们从头开始。 And the beginning in REST is that we have to first request the / (root), then it returns list of paths we can further retrieve, etc, etc. Isn't this the the first part where REST is completely wasteful? REST的开始是我们必须首先请求/(根),然后它返回可以进一步检索的路径列表,等等,等等。这不是REST完全浪费的第一部分吗? Instead of rigid paths, we have to obtain them each time we want to do something. 代替固定的路径,我们每次想做某事时都必须获取它们。 Nah. 罗。

The second problem I encountered was bulk operations . 我遇到的第二个问题是批量操作 How to implement them in REST? 如何在REST中实现它们? Let's say, user didn't have access to the internet for a while, made a few changes and they all have to be made on server as well. 假设用户暂时无法访问互联网,进行了一些更改,并且都必须在服务器上进行。 So, let's say user modified 50 notes, added 30 and removed 20. We have to make 100 separate requests now. 假设用户修改了50个便笺,添加了30个便笺,然后删除了20个便笺。我们现在必须发出100个单独的请求 A way to make bulk operations would be very helpful - I saw this stackoverflow topic: Patterns for handling batch operations in REST web services? 进行批量操作的方法将非常有用-我看到了这个stackoverflow主题: 在REST Web服务中处理批处理操作的模式? but I didn't found anything interesting here actually. 但实际上我没有发现任何有趣的东西。 Everything is okay as long as you want to do one type of operation on one type of resources. 只要您想对一种资源进行一种操作就可以了。

Last, but not least - retrieving whole collection of items. 最后但并非最不重要的-检索整个项目集合。 When writing an example app I mentioned - notes app - you probably want to retrieve all collection of items (notes, tags, available notes colors, etc...) at once. 在写一个我提到的示例应用程序(便笺应用程序)时,您可能想一次检索所有项目集合(便笺,标签,可用的便笺颜色等)。 With REST, you have to first retrieve list of item links, then fetch the items one by one. 使用REST,您必须首先检索项目链接列表,然后一个个地获取项目。 100 notes = over 100 requests. 100笔记=超过100个请求。

Since I'm currently learning all this REST stuff, I may be completely wrong at what I said here. 由于我目前正在学习所有这些REST知识,所以我在这里所说的可能完全错了。 Anyway, the more I read about it, the more gruesome it looks like for me. 无论如何,我读得越多,对我来说看起来就越可怕。 So my question finally is: where am I wrong and/or how to solve problems I mentioned? 所以最后我的问题是:我在哪里错和/或如何解决我提到的问题?

It's all about resources . 这都是关于资源的 Resources that are obtained through a uniform interface (usually via URI and HTTP methods). 通过统一接口(通常通过URI和HTTP方法)获得的资源。

  1. You do not have to navigate through root every time. 不必通过根每次进行导航。 A good interface keeps their URIs alive forever (if they go stale, they should return HTTP Moved or similar). 一个好的接口可以使它们的URI 永远存活(如果过时,则应返回HTTP Moved或类似的消息)。 Root offering pathways to navigate is a part of HATEOAS , one of Roy Fieldings defined architectural elements of REST. Root Fieldings定义的REST架构元素之一是HATEOAS的一部分, 提供根目录的导航路径。
  2. Bulk operations are a thing the architectural style is not strong on. 批量操作是一种架构风格不强的东西。 Basically nothing is stopping you to POST a payload containing multiple items to a specific resource. 基本上没有什么阻止你POST包含多个项目的特定资源的有效载荷。 Again, it's all up to what resource you are using/offering and ultimately, how your server implementation handles requests. 同样,这完全取决于您使用/提供的资源,最终取决于服务器实现如何处理请求。 Your case of 100 requests: I would probably stick with 100 requests. 您的100个请求的案例:我可能会坚持100个请求。 It is clean to write and the overhead is not that huge. 编写起来很干净,开销也不是那么大。
  3. Retrieving a collection: It's about resources what the API decides to offer. 检索集合:这是API决定提供的资源 GET bookCollection/ vs GET book/1 , GET/book/2 ... or even GET book/all . GET bookCollection/ vs GET book/1GET/book/2 ...甚至GET book/all Or maybe GET book/?includeDetails=true to return all books with same detail as GET ting them one-by-one. 或者也许是GET book/?includeDetails=true来返回所有与GET一一对应的细节相同的书。

I think that this link could give you interesting hints to design a RESTful service: https://templth.wordpress.com/2014/12/15/designing-a-web-api/ . 我认为此链接可以为您设计RESTful服务提供有趣的提示: https : //templth.wordpress.com/2014/12/15/designing-a-web-api/

That said, here are my answers to your questions: 也就是说,这是我对您的问题的回答:

  • There is no need to implement a resource for the root path. 无需为根路径实现资源。 With this, I think that you refered to HATEOS. 因此,我认为您是指HATEOS。 In addition, no link within the payload is also required. 另外,还不需要有效载荷内的链接。 Otherwise you can use available formats like Swagger or RAML to document your RESTful service. 否则,您可以使用Swagger或RAML等可用格式来记录RESTful服务。 This show to your end users what is available. 这向您的最终用户显示可用的内容。

  • Regarding bulk operations, you are free to use methods POST or PATCH to implement this on the list resource. 关于批量操作,您可以自由使用POSTPATCH方法在列表资源上实施此操作。 I think that these two answers could be helpful to you: 我认为这两个答案可能对您有所帮助:

  • In fact, you are free to regarding the content you want for your methods GET . 实际上,您可以随意考虑方法GET所需的内容。 This means the root element managed by the resources (list resource and element resource) can contain its hints and also the ones of dependencies. 这意味着由资源(列表资源和元素资源)管理的根元素可以包含其提示以及依赖项。 So you can have several levels in the returned content. 因此,您可以在返回的内容中包含多个级别。 For example, you can have something like this for an element Book that references a list of Author : 例如,您可以为元素Book引用这样的内容,该元素引用Author的列表:

     GET /books { "title": "the title", (...) "authors": [ { "firstName": "first name", "lastName": last name" }, { (...) }, (...) ] } 

    You can notice that you can leverage query parameters to ask the RESTful service to get back the expected level. 您会注意到,您可以利用查询参数来要求RESTful服务恢复期望的水平。 For example, if you want only book hints or book hints with corresponding authors: 例如,如果您只想要书的提示或与相应作者的书的提示:

     GET /books { "title": "the title", (...) } GET /books?include=authors { "title": "the title", (...) "authors": [ { "firstName": "first name", "lastName": last name" }, { (...) }, (...) ] } 

    You can notice that you can distinguish two concepts here: 您会注意到,您可以在此处区分两个概念:

    • The inner data (complex types, inner objects): data that are specific to the element and are embedded in the element itself 内部数据 (复杂类型,内部对象):特定于元素并嵌入元素本身的数据
    • The referenced data : data that reference and correspond other elements. 引用数据 :引用并对应其他元素的数据。 In this case, you can have a link or the data itself embedded in the root element. 在这种情况下,您可以在根元素中嵌入一个链接或数据本身。

    The OData specification addresses such issue with its feature "navigation links" and its query parameter expand . OData规范通过其功能“导航链接”及其查询参数expand解决此类问题。 See the following links for more details: 有关更多详细信息,请参见以下链接:

Hope it helps you, Thierry 希望对您有帮助,蒂埃里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM