如何设计 RESTful API 向用户提供 returns 建议的端点
How to design a RESTful API endpoint that returns a suggestion to a user
我正在构建一个处理用户和建议的 RESTful API。我达到了需要构建建议资源的地步,它应该 嵌套 在用户资源中并且应该 return 一个计算建议(这意味着它不存在然而 - 它是在发出请求时即时创建的。
我想做一个像users/<id>/suggestion
这样的路由,但感觉不对:可以users/<id>/suggestions
获取所有用户的建议,或者users/<id>/suggestion/<id2>
获取一个该用户的特别建议。在这种情况下,我需要构建 3 个资源,一个用于处理 return 计算出的建议,一个用于处理所有建议,另一个用于处理特定的现有建议。
那么,GET
是否适合检索新 创建、计算的对象?听起来很自然,但我不知道这是否是真正的 REST。如果不行,应该用什么方法?
感谢您对此提供的任何帮助。如果您想知道 language/framework 我用的是什么,部分是 Flask/Flask RESTful 和 Rails/Sinatra.
我认为您有几个选择,这取决于您如何使用这些建议。
瞬态模型
在简单的情况下,只支持瞬态(即在服务器上无状态):
/用户//建议
您可以将其缓存一段时间,而不实际在服务器上存储任何建议。在那种情况下,您可能不会提供个人建议 API(/users//suggestions/123 不受支持)。相反,响应中的每个结果都是 其他 资源的 RESTful 表示。
ie /users//建议可以 return:
[
{
"type": "book",
"name": "Some book",
"author": "Some author",
"url": "https://yoursite.com/books/123"
},
{
"type": "movie",
"name": "Some movie",
"producer": "Some movie",
"url": "https://yoursite.com/books/123"
}
]
一种变体是为每种类型提供不同的部分,即 { books: [], movies: [] }。您还可以将这些异构模型包装在具有置信度等的 "suggestion" 资源中。但是建议包装器没有 ID 或 URL,因为服务器上不存在建议。
坚持模型
如果您希望建议更像第一个 class 公民,可以单独获取,那么您应该创建类似 SuggestionSet 资源的内容。它接受一个 post 请求和 return 一个 URL 用于新的 SuggestionSet,例如在 //suggestion-sets/123。然后客户端可以执行进一步的 GET 请求来检索集合,它将列出所有单独的项目。
另一种方法是为每个用户预先构建建议。显然,这不能很好地扩展,但对于小型系统来说已经足够了。您还可以将它与前面示例中的方法结合起来,即为活跃用户预取,并且仍然支持 POST 不活跃用户。
您需要定期清理旧的建议集。
短暂的还是持久的?
在大多数情况下,瞬态模型应该没问题。持久化模型有两个主要好处:
您可以通过在您的问题 (users//suggestion/) 中请求个别建议来深入了解建议的详细信息。但请注意,这些是包含建议元数据的建议包装对象(例如,关于用户可能喜欢它的原因、置信度等的评论),它们不是用户案例所涉及的实际建议资源(例如书籍和电影),这些资源已经可通过现有 API 调用获得。
这才是真正的好处 - 您可以异步处理建议。如果将其设为 GET 调用,则需要在几分之一秒内构建所有建议,以便可以 return 在非阻塞响应中编辑它们。如果您首先需要 POST,则可以期望客户端进行轮询,直到建议集准备就绪。
我正在构建一个处理用户和建议的 RESTful API。我达到了需要构建建议资源的地步,它应该 嵌套 在用户资源中并且应该 return 一个计算建议(这意味着它不存在然而 - 它是在发出请求时即时创建的。
我想做一个像users/<id>/suggestion
这样的路由,但感觉不对:可以users/<id>/suggestions
获取所有用户的建议,或者users/<id>/suggestion/<id2>
获取一个该用户的特别建议。在这种情况下,我需要构建 3 个资源,一个用于处理 return 计算出的建议,一个用于处理所有建议,另一个用于处理特定的现有建议。
那么,GET
是否适合检索新 创建、计算的对象?听起来很自然,但我不知道这是否是真正的 REST。如果不行,应该用什么方法?
感谢您对此提供的任何帮助。如果您想知道 language/framework 我用的是什么,部分是 Flask/Flask RESTful 和 Rails/Sinatra.
我认为您有几个选择,这取决于您如何使用这些建议。
瞬态模型
在简单的情况下,只支持瞬态(即在服务器上无状态): /用户//建议
您可以将其缓存一段时间,而不实际在服务器上存储任何建议。在那种情况下,您可能不会提供个人建议 API(/users//suggestions/123 不受支持)。相反,响应中的每个结果都是 其他 资源的 RESTful 表示。
ie /users//建议可以 return:
[
{
"type": "book",
"name": "Some book",
"author": "Some author",
"url": "https://yoursite.com/books/123"
},
{
"type": "movie",
"name": "Some movie",
"producer": "Some movie",
"url": "https://yoursite.com/books/123"
}
]
一种变体是为每种类型提供不同的部分,即 { books: [], movies: [] }。您还可以将这些异构模型包装在具有置信度等的 "suggestion" 资源中。但是建议包装器没有 ID 或 URL,因为服务器上不存在建议。
坚持模型
如果您希望建议更像第一个 class 公民,可以单独获取,那么您应该创建类似 SuggestionSet 资源的内容。它接受一个 post 请求和 return 一个 URL 用于新的 SuggestionSet,例如在 //suggestion-sets/123。然后客户端可以执行进一步的 GET 请求来检索集合,它将列出所有单独的项目。
另一种方法是为每个用户预先构建建议。显然,这不能很好地扩展,但对于小型系统来说已经足够了。您还可以将它与前面示例中的方法结合起来,即为活跃用户预取,并且仍然支持 POST 不活跃用户。
您需要定期清理旧的建议集。
短暂的还是持久的?
在大多数情况下,瞬态模型应该没问题。持久化模型有两个主要好处:
您可以通过在您的问题 (users//suggestion/) 中请求个别建议来深入了解建议的详细信息。但请注意,这些是包含建议元数据的建议包装对象(例如,关于用户可能喜欢它的原因、置信度等的评论),它们不是用户案例所涉及的实际建议资源(例如书籍和电影),这些资源已经可通过现有 API 调用获得。
这才是真正的好处 - 您可以异步处理建议。如果将其设为 GET 调用,则需要在几分之一秒内构建所有建议,以便可以 return 在非阻塞响应中编辑它们。如果您首先需要 POST,则可以期望客户端进行轮询,直到建议集准备就绪。