【问题标题】:How to organise resources in web application URL structure如何在 Web 应用程序 URL 结构中组织资源
【发布时间】:2016-10-10 14:17:42
【问题描述】:

现状

我正在使用 PHP 开发一个在线订单管理系统应用程序,我需要通过 URL 方案设计 REST 资源映射。

我有典型的资源:

  • 客户(有订单)
  • 订单(有票)
  • 票证(有消息)
  • 留言

我在想这样的事情:

  1. 客户资料:

    example.com/customers/{customer-ID}
    
  2. {customer-ID} 的订单:

    example.com/customers/{customer-ID}/orders
    
  3. {order-ID} 的门票:

    example.com/customers/{customer-ID}/orders/{order-ID}/tickets
    
  4. {ticket-ID} 的消息

    example.com/customers/{customer-ID}/orders/{order-ID}/tickets/{ticket-ID}/messages
    

调查结果

在谷歌上搜索了一天,我找到了这些引用:

  1. 用户名后面的命名空间功能,如

    example.com/{username}/followers
    

    对于属于每个用户的公共功能是很好的解决方案。

  2. 诸如帐户设置之类的私人内容不应在用户名后面进行命名空间,而应仅出现在/account/settings 之后。

  3. 最好使基本资源 URL 尽可能精简。 过滤器排序要求、高级搜索分页都可以实现为查询参数.

  4. 查询字符串应被视为页面的可选添加;该 URL 应该能够生成有效且有用的页面,即使它已被删除。

  5. 在一个良好的可破解网址中,人类可以调整或删除部分路径并从您的网站获得预期的结果。它们可以让您的访问者更好地了解您的网页,并使他们能够轻松地向上移动。

  6. 通过在您的路径中尽早嵌入唯一 ID,您可以在需要时拥有完整的长网址,但仍然可以享受较短网址的可靠性和 ID 查找速度。

  7. 向 URL 添加多个关键字可能有助于 SEO,但它会使您的用户感到困惑。此外,您很快就会面临被标记为关键字垃圾邮件发送者的风险。

问题

  • 我做错了吗?
  • 我应该避免命名customersordersticketsmessages吗?
  • 它有什么真正的重大安全问题吗?

提前致谢!

【问题讨论】:

    标签: php rest url url-rewriting url-routing


    【解决方案1】:

    如果您描述的所有关系都是一对多(不是多对多),那么我真的看不出您通过使用包含客户 id 的 URL 获得什么,而订单 id 是已知的.它是冗余信息,不会在您的控制器中提供额外的有用信息。

    事实上,它可能会导致比预期更多的复杂性,因为现在您必须处理可能是客户与订单 ID 不匹配的情况。您现在必须检查所有这些条件并在出现这些不良条件时返回错误的请求响应。为什么要增加开销?

    也许只是:

    客户资料:

    example.com/customers/{customer-ID}
    

    {customer-ID} 的订单:

    example.com/customers/{customer-ID}/orders
    

    {order-ID} 的门票:

    example.com/orders/{order-ID}/tickets
    

    {ticket-ID} 的消息

    example.com/tickets/{ticket-ID}/messages
    

    如果你有一个多对多的关系,这可能会改变。例如,假设客户可以输入包含多个订单的单张票(这意味着票现在与客户的相关性比与订单本身的相关性更高),那么除了上面显示的 URL 之外,您可能还需要以下 URL:

    查看给定票的所有订单:

    example.com/tickets/{ticket-ID}/orders
    

    查看客户的所有票证:

    example.com/customer/{customer-ID}/tickets
    

    【讨论】:

    • 在你推荐的方案中,example.com/customers/{customer-ID}/ordersexample.com/orders有什么区别?
    • @Trix /orders 可能会列出所有订单,而 /customers/{customer-ID}/orders 会列出该客户 ID 的所有订单。
    • 那么,当客户访问/orders 时,他应该看到什么? 拒绝访问! 消息?!
    • @Trix 这由您决定。如果您有一个最终用户(而不是管理员用户)的用例来查看完整的订单列表,那么您可以返回完整列表。如果那里没有适合 edn 用户的用例,则您对此方法的授权应该会导致返回适当的 4XX 或 5XX 系列响应。
    • @Trix 继续我的评论... 通常,在 RESTful 服务中,您不会使用授权作为过滤结果集的机制。您使用授权来允许访问应用程序中的某些路由。出于这个原因,我不建议使用/orders 结合授权数据来过滤订单结果集到仅与最终客户相关的订单。这就是数据库中的关系信息的用途。
    【解决方案2】:

    我做错了吗?

    这取决于。您似乎走在正确的轨道上,但您最好决定您的服务应该首先提供哪些功能。否则,您最终可能会得到无限数量的 url(resources) 来实现。例如,如果您需要在所有客户端上公开订单列表,您将希望拥有带有查询字符串参数的example.com/orders 资源来指定搜索条件。否则,必须先查询所有客户端,然后在循环中向example.com/customers/{customer-ID}/orders 发送请求以获取所有客户端的所有订单。 因此,首先考虑您的服务需要公开哪些功能,然后为其设计资源。

    它有什么真正的重大安全问题吗?

    它与 url(resources) 设计无关。身份验证和授权信息通常放在 http 标头中。

    另外,请考虑在您的网址中添加版本信息。当您必须支持多个版本的服务时,它会非常有用

    example.com/v1/customers/{customer-ID}/orders
    

    v1.example.com/customers/{customer-ID}/orders
    

    等等

    最后,如果您要支持资源的多种表示,例如,您可以将客户端列表返回为 JSON、XML、HTML 等。在 url 中指定它也是一个好习惯。因此,决定您的默认表示格式并将其公开为example.com/customers,然后在您支持其他人的情况下将格式信息添加到 url 的末尾

    example.com/customers.xml
    

    example.com/customers.html
    

    等等

    希望对你有帮助!

    我认为在 URL 中包含 ID 可能不是一个好习惯

    嗯,有两种主要的方法,都有它的缺点和优点。第一个是使用名称或简短的资源描述而不是 ID。例如,您可以使用其名称 example.com/customers/amazon 代替客户端 ID,其中 amazon 是您的客户端名称。该方法的另一个很好的例子是新闻网站,如果您浏览cnn.com,您会看到每篇文章的网址都包含文章标题http://edition.cnn.com/2016/06/10/middleeast/israel-tel-aviv-shooting/index.html - “特拉维夫嫌疑人被发现躲在下班警察的家中”

    从 SEO 的角度来看,这非常棒,并且网址变得更具描述性和人性化。但是,如果您必须更改您的客户名称,则应该更改 url,并且存在破坏客户的巨大风险。此外,在实施该方法时要记住很多事情:

    • 您应该正确验证客户名称,以便可以将它们添加到 URL 中
    • 您应该禁止更改客户名称或通过返回 301(“永久移动”)并在 Location 标头中指定新 url 来正确处理它,以便客户端知道新 url

    ID 方法的主要优点是 url 始终是静态的,您不必为上面的实现而烦恼。

    从 REST 角度来看,这两种方法都是有效的,因此由您决定

    【讨论】:

    • 所以首先考虑您的服务需要公开哪些功能,然后为其设计资源。 :客户有订单,而订单又可能有票,每个票有多个消息。功能很明显,因为客户应该能够提交订单。在他们的订单上提交票证并向他们的票证添加消息
    • @Trix 是的,但是您可能有管理员可能需要按照我的回答中所述查询所有客户的订单,可能还有其他情况,如 Mike 所述。这只是一个建议,所以你不会错过任何东西。如果您在上面指定的内容是您服务应该公开的所有内容,那么正如我在回答中所说的那样,您就在正确的轨道上
    • 谢谢,但是很明显,任何应用程序都需要一些管理员的东西。我想知道这样公开资源是否是一种好的做法,并有令人信服的证据支持
    • @Trix “公开资源”到底是什么意思?你的意思是我的例子,在 url 中有和没有客户 ID 的订单?
    • IDTitle 之间没有真正的区别。两者都需要在路由级别进行检查。博客文章和新闻项目也是公共资源,而客户订单则不是。我想你对我的问题有误解。
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    相关资源
    最近更新 更多