带有分页、排序和过滤的 WebAPI Get 方法
Posted
技术标签:
【中文标题】带有分页、排序和过滤的 WebAPI Get 方法【英文标题】:WebAPI Get method with Paging, Sorting and Filtering 【发布时间】:2020-09-08 12:02:02 【问题描述】:我正在创建一个 WebAPI,其中 get 方法需要接受分页、排序和过滤等参数。 由于排序和过滤可以是键值对的列表,并且过滤也有运算符(gt、lt、equals、contains...),而且我们知道不建议在 get 方法中发送 body 中的对象,这是怎么回事为 API 处理的场景?
【问题讨论】:
【参考方案1】:只需将它们传递为Query String
。
这是分页、排序和过滤等行为的最佳实践,因为它可以被用户添加书签并重复使用。
您可以在许多著名网站上看到您的答案,例如在 SO 中查看下面的过滤器参数:
https://***.com/questions?sort=Newest&filters=NoAnswers,NoAcceptedAnswer,Bounty
@AdrianoRepetti 在 cmets 中有很多有用的互补性,我在获得许可的情况下添加了这些互补性:
有几种不同的方法:
例如排序:
http://www.example.com/api/orders?sort=field1,field2
或http://www.example.com/api/order?sort=field1&sort=field2
现在让它变得更好:您还需要排序顺序,它可以很好地表示为:
http://www.example.com/api/orders?sort=created_at+asc,delivered_at+desc.
过滤器可能更复杂。一个简单的场景:
http://www.example.com/api/order?filter=status%3dpending(注意 %3d 转义 =,API 将看到 status=pending
作为过滤器参数)。您需要更多的 ANDed 过滤器吗?只需连接或重复它们(如排序)。如果您支持其他运算符,则可以使用其他字符而不是 %3d。如果事情变得更复杂,那么您将需要自己的迷你语言来表达您的过滤器(记住对客户端的 URI 组件进行编码!!!)
迟早您需要使查询变得更复杂,然后太长而无法放入查询字符串中(例如,当您需要IN
运算符时)。对于此类查询,使用POST
而不是GET
是完全可以接受的(并且被广泛使用)(例如,参见OpenData
)。你可以为你的过滤器想出一些更复杂的方案,但是一个简单的JSON
对象(或下摆GraphQL
)通常是一个更好、更容易的选择
【讨论】:
详细说明:有几种不同的方法。先排序:example.com/api/orders?sort=field1,field2
或 example.com/api/order?sort=field1&sort=field2
。
过滤器可能更复杂。一个简单的场景:example.com/api/order?filter=status%3dpending
(注意 %3d 转义=
,API 将查看 "status=pending"
以获取filter
参数)。您需要更多的 ANDed 过滤器吗?只需连接或重复它们(如排序)。如果您支持其他运算符,则可以使用其他字符而不是 %3d
。如果事情变得更复杂,那么您将需要自己的迷你语言来表达您的过滤器(请记住对客户端的 URI 组件进行编码!!!)。
现在让它变得更好:您还需要排序顺序,它可以很好地表示为example.com/api/orders?sort=created_at asc,delivered_at desc
。迟早您将需要使查询更复杂,然后太长而无法放入查询字符串中(例如,当您需要 IN
运算符时)。对于此类查询,使用 POST
而不是 GET
是完全可以接受的(并且被广泛使用)(例如,参见 opendata)。你可以为你的过滤器想出一些更复杂的方案,但一个简单的 JSON 对象(或 hem hem GraphQL)通常是更好、更容易的选择。
@ArmanEbrahimpour 如果您认为它对未来的读者有用,请随时更新此答案
@elector 是的,特别是如果过滤器是一个复杂的表达式,让它“准备好使用”比解析字符串要容易得多。与 curl
一起使用的 API 对 UX 不友好,但典型的 Web 客户端不会有太大区别。以上是关于带有分页、排序和过滤的 WebAPI Get 方法的主要内容,如果未能解决你的问题,请参考以下文章