【问题标题】:a restful api only uses clean urls - no url variables or post variablesrestful api 只使用干净的 url - 没有 url 变量或 post 变量
【发布时间】:2012-07-17 12:55:37
【问题描述】:

restful api 必须使用 get、post、put 或 delete 请求方法。提交的行为和数据完全由 uri 字符串决定。没有查询参数或发布变量。

这是真的吗?

有效:http://example.com/foo/84

无效http://example.com/foo/?value=84

有效:

$.ajax({
  type: 'POST',
  url: "http://example.com/foo/84",
  success: success,
  dataType: dataType
});

无效

$.ajax({
  type: 'POST',
  url: "http://example.com/foo/",
  data: 84,
  success: success,
  dataType: dataType
});

编辑 到目前为止的两个答案,并且相互矛盾。

【问题讨论】:

    标签: rest restful-url


    【解决方案1】:

    这是与其他两个相矛盾的第三个答案。

    RESTful URI 几乎是矛盾的。 URI 的语义与 REST 无关,唯一对 REST 重要的是一个 URI 只标识一个资源。除此之外,URI 是一个原子标识符,它的语义是无关紧要的。

    对于 REST,指向 Joe Doe 的用户资源的 URI 是否为:

    http://example.com/users/joedoe
    

    或者:

    http://example.com/users?username=joedoe
    

    或者:

    http://example.com/jif892mfd02-18f2
    

    甚至:

    ftp://example.com/users/joedoe.json
    

    没关系! URI 在 RESTful 应用程序中不需要有任何意义。人们花了很多时间为他们的 REST 应用程序设计有意义的 URI,同时他们应该关心他们的媒体类型。当您点击网页上的链接时,您不关心 URI 的语义,您只关心标签。使用 REST API 的客户端也会发生同样的事情。您的媒体类型的文档应通过标签描述哪些链接可用以及它们的作用,您只需按照它们进行操作即可。

    如果您关心 URI 的语义,这表明您的客户端正在从文档中的某个模板构建 URI,而您没有使用 HATEOAS,这意味着您根本没有使用 REST。

    【讨论】:

    • 但是,当您是一名必须与该 API 集成并使用它的开发人员时,拥有一个设计良好并遵循现有惯例的 API 确实会有所帮助。此外,有些人有时必须手动输入网址,因此拥有一个易于阅读的网址可以提高阅读率或转化率。那些没有?和 = 对人类来说更容易解析,至少不是超级天才的普通人更容易解析。 :D
    • 不。如果您是与 RESTful API 集成的开发人员,您将遵循资源提供的 URI。如果你做对了,你可能永远不需要直接处理一个URI,而不是把它存储在一个变量中然后使用这个变量。如果服务要求您从文档中给出的模板构建 URI,那么它不是 RESTful,就这么简单。
    • 当然,这并不意味着您不应该考虑您的 URI。它只是意味着遵循约定 X 或 Y 的 URI 不会使您的 API 或多或少 RESTful。使您的 API 成为 RESTful 的是您向客户端提供 URI 的方式。
    • 我想说的是,如果您是一个与 RESTful 服务集成的开发人员,那么如果 url 遵循统一的界面或模式,事情的结构会更加清晰。例如 /users/employees/john 告诉我们 John 是员工集合的一部分,而 /users/clients/beth 告诉我们 Beth 是客户集合的一部分。这比 /getClient?name=beth 要清楚得多。两者都告诉你一些事情。但前者直观地告诉你完整的层次结构。
    • 错了。 URI 不应该告诉您 john 是员工而 beth 是客户。他们的媒体类型应该,而且无论他们在哪里。您可以将 /users/1 用于 john,将 /users/2 用于 beth,返回 john 的媒体类型为员工,beth 为客户。服务器可以完全控制 URI 命名空间,并且可以随时更改它们。如果您依赖 URI 获取该信息,那么您的 API 不是 RESTful。
    【解决方案2】:

    POST 变量肯定没问题,否则你将如何提交或更新新资源?

    GET 参数可以很好地指定资源的呈现方式。所以确实http://example.com/foo/?value=84 是不对的——URL 不代表资源。

    但是,http://example.com/user/84?fields=first_name,last_name 可以。在这种情况下,您将使用其他查询参数来指定您只需要该资源的名字和姓氏。

    【讨论】:

    • 发布变量:通过指定 url 中的数据,我认为这有点老实。
    • @NimChimpsky 想想数据和表示之间的区别。例如,可以通过 /users 访问用户列表,但您可能希望按姓氏 /users?sort=lastname 进行排序。它仍然是相同的数据,只是呈现方式略有不同。
    • @ZetaTwo 那么 rest 到底具体定义了什么?据我所知,它只是使用 http 请求访问和检索数据的另一个名称。它建议使用删除和放置来删除和插入数据的约定?顺便说一句,另一个答案与这个答案相矛盾。
    • @NimChimpsky 这不仅仅是关于 URL。如需快速概览,请阅读 WP 文章的这一部分:en.wikipedia.org/wiki/…
    • 嗯? ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm 没有提到“GET 参数可以很好地指定资源的呈现方式”。它确实说“任何可能成为作者超文本引用目标的概念都必须符合资源的定义。”概括地说,这意味着您可以合法构建的每个 URL 都是 RESTful 如果它标识了客户想要标识的概念。
    【解决方案3】:

    http://example.com/foo/?value=84 无效并不完全正确。我的意思是,只要它是一个有效的 URL,它就可以工作,并且您将能够通过 get 或 post 获取参数。

    另一方面,REST 是一种架构,其要求之一是干净的 URL(不包含带有“?”的参数),因此这样的 URL 不被视为类似于 REST 的 URL。

    因此,如果您打算构建基于 REST 的应用程序,您应该只使用干净的 url。

    编辑:

    我从下面的 cmets 中看到,您在理解什么是 REST 方面存在问题,所以我将尝试举一个简单的示例:

    1. 为了获取数据,您可能会使用http://example.com/foo/84 作为获取请求,而其余 FW 知道获取 id 为 84 的资源 foo。
    2. 为了发布有关 foo 的数据,您可以调用:http://example.com/foo/84 作为 POST 请求,现在 Rest FW 知道,由于它是一个 post 请求,它将调用负责处理 post 的方法,而不是处理 get 的方法
    3. 要删除,您可以使用 DELETE 操作调用相同的 URL,我想您知道其余的。

    所以,虽然你有相同的 URL,但它是否是 GET/POST/PUT/DELETE 请求真的很重要。

    【讨论】:

    • 我不认为我们的答案不同,尽管它们的表述方式不同。对于一个被认为是 RESTful 的 Web API,它需要遵循一定的模式。 /foo/?value=84 会起作用,这是真的,但它不会是 REST API。如果您以这种方式访问​​资源,您将错过 REST API 的某些优势,尤其是缓存。
    • @Laurent yr answer 中的第二个示例在 url 中使用查询参数。它不干净,但你说它很安静。而这个答案说restful不能在get请求中使用url参数。
    • @NimChimpsky,您需要查看有无查询参数:无论您获得/user/84?fields=first_name,last_name 还是/user/84,您都会获得相同的用户,尽管具有不同的字段。然而,如果你比较/user/?id=84/user/ - 在一种情况下你会得到一个用户,在第二种情况下你什么也得不到,缺乏一致性。基本上,如果添加或更改查询参数返回不同的资源,则说明 API 存在问题。
    • @Laurent 如果您指定 first_name,您将获得与指定 last_name 不同的数据。这似乎与你所说的相矛盾。当然,相关字段的显示将由视图而不是控制器(服务器)处理,因此不应使用查询参数?
    • @NimChimpsky,不,无论您查询 last_name 还是 first_name,您仍然获得相同的资源。从理论上讲,视图确实应该处理显示相关字段,并且不需要查询参数。在实践中,您将需要查询参数,这样您就不会每次都传输整个资源。这几乎是一种优化技术。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2011-04-02
    • 2015-05-10
    • 1970-01-01
    相关资源
    最近更新 更多