使用一长串查询参数设计RESTful查询API

所以,我需要设计一个RESTful查询API,它基于几个过滤器返回一组对象。 通常的HTTP方法是GET。 唯一的问题是,它可以有至少十几个过滤器,并且如果我们将它们全部作为查询参数传递,URL可能会变得很长(足够长以被防火墙阻止)。

减少参数数量不是一种选择。

我能想到的另一种方法是在URI上使用POST方法,并将过滤器作为POST主体的一部分发送。 这是反对RESTfull(进行POST调用查询数据)。

任何人有更好的设计建议?

谢谢


请记住,使用REST API,这都是您的观点问题。

REST API中的两个关键概念是端点和资源(实体)。 宽松地说,端点通过GET返回资源或通过POST和PUT等(或上述组合)接受资源。

可以接受的是,通过POST,您发送的数据可能会或可能不会导致创建新资源及其关联的终端,而这些终端很可能不会在POST网址下“活”。 换句话说,当你POST时你发送数据的地方进行处理。 POST端点不是通常可以找到资源的位置。

引用RFC 2616(省略不相关的部分,并强调相关部分):

9.5 POST

POST方法用于请求源服务器接受请求中包含的实体作为Request-Line中Request-URI标识的资源的新下属。 POST旨在允许统一的方法来涵盖以下功能:

  • ...
  • 向数据处理过程提供一组数据,例如提交表单的结果;
  • ...
  • ...

    POST方法执行的操作可能不会导致可以通过URI标识的资源 。 在这种情况下,200(OK)或204(无内容)是适当的响应状态,具体取决于响应是否包含描述结果的实体

    如果在原始服务器上创建了一个资源,那么响应应该是201(创建)...

    我们已经习惯了代表“事物”或“数据”的终端和资源,无论是域,用户,消息还是书籍。 但是,端点也可以公开不同的资源 - 例如搜索结果。

    考虑下面的例子:

    GET    /books?author=AUTHOR
    POST   /books
    PUT    /books/ID
    DELETE /books/ID
    

    这是一个典型的REST CRUD。 但是,如果我们添加:

    POST /books/search
    
        {
            "keywords": "...",
            "yearRange": {"from": 1945, "to": 2003},
            "genre": "..."
        }
    

    这个端点没有什么不可靠的。 它以请求主体的形式接受数据(实体)。 该数据是搜索标准 - 与其他任何DTO一样。 该端点响应请求产生资源(实体): 搜索结果 。 搜索结果资源是一个临时的资源,立即向客户端提供,没有重定向,也没有从其他规范网址公开。

    它仍然是REST,除了实体不是书籍 - 请求实体是书籍搜索条件,并且响应实体是书籍搜索结果。


    许多人已经接受这样一种做法:具有太长或太复杂查询字符串的GET(例如,查询字符串不能轻松处理嵌套数据)可以作为POST发送,而用体内表示的复杂/长数据的请求。

    在HTTP规范中查找POST规范。 它非常广泛。 (如果你想通过REST中的漏洞航行战舰......请使用POST。)

    你失去了GET语义的一些好处,比如自动重试,因为GET是幂等的,但是如果你能忍受,那么接受POST处理真正长或复杂的查询可能会更容易。

    (大声笑长题外话......我最近发现,通过HTTP规范,GET可以包含一个文档主体,有一个部分说,解释说:“任何请求可以有一个文档主体,除了本节中列出的文档主体”...并且它所指的部分没有列出任何内容我搜索并找到了一个HTTP作者正在谈论的线程,这是故意的,以便路由器等不必区分不同的消息。实践中很多基础设施部分都会抛弃GET的主体,因此您可以使用体内代表的过滤器进行GET,例如POST,但是您会掷骰子。)


    简而言之:使用X-HTTP-Method-Override标题创建POST但覆盖HTTP方法。

    真正的要求

    POST /书籍

    实体主体

    {“title”:“Ipsum”,“年份”:2017}

    X-HTTP-Method-Override:GET

    在服务器端,检查是否存在标题X-HTTP-Method-Override,然后将其值作为构建到后端最终端点的路径的方法。 另外,将实体主体作为查询字符串。 从后端角度来看,请求变成了一个简单的GET。

    通过这种方式,您可以使设计与REST原则保持一致。

    编辑:我知道这个解决方案最初是为了解决某些浏览器和服务器中的PATCH动词问题,但在问题中描述的问题很长的URL的情况下,它也适用于GET动词。

    链接地址: http://www.djcxy.com/p/71375.html

    上一篇: Design RESTful query API with a long list of query parameters

    下一篇: REST API 404: Bad URI, or Missing Resource?