RESTful API 路由设计:嵌套与非嵌套 [英] RESTful API routes design: nested vs. non-nested

查看:50
本文介绍了RESTful API 路由设计:嵌套与非嵌套的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是关于为 API 目的构建 URL 时嵌套资源的优势.考虑以下两种访问员工资源的方法:

My question is about the advantages of nesting resources when building URLs for API purposes. Consider the following two alternatives for accessing an employee resource:

/api/employees?department=1   # flat

Vs.

/api/departments/1/employees  # nested

现在考虑开发通用库以从 API 访问 REST 资源的任务.如果所有路由都是扁平的,那么这样的 REST 包装器库只需要知道被访问的资源的名称:

Now consider the task of developing a general purpose library to access REST resources from an API. If all routes were flat, such a REST wrapper library would only need to know the name of the resource being accessed:

store.query('employees', {department_id:1})   =>   /api/employees?department=1

然而,如果我们要支持嵌套路由,这个包装器需要知道关于哪些模型被嵌套以及在哪些其他资源下的额外信息,以便知道如何构建用于引用此类模型的 URL.鉴于并非所有模型都嵌套在同一个父资源下,甚至一些模型根本不会嵌套,REST 包装器库需要有某种配置来描述所有这些额外的知识,否则就不需要这些知识.

However, if we were to support nested routes, this wrapper would need to know extra information about what models are nested and under which other resource, in order to know how to build the URLs for referencing such a model. Given that not all models would be nested under the same parent resource, and even some models would not be nested at all, the REST wrapper library would need to have some sort of configuration describing all this extra knowledge that wouldn't be needed otherwise.

所以我的问题是:

  • 在 API 中嵌套资源路由有什么真正的优势吗?(这并不意味着最终用户会使用它,因此从拥有更漂亮的 URL 中获得的收益更少.

  • Are there any real advantages to nested resource routes in an API? (Which is not meant to be consumed by end users, and therefore gains less from having prettier URLs).

嵌套方法真的比扁平化更好吗,超越美学,从而证明为支持资源 URL 构建缺乏统一性而引入的额外努力和复杂性是合理的?

Is the nested approach really better than flat, beyond aesthetics, so as to justify the extra effort and complexity introduced to support the lack of uniformity in resource URL building?

另见:https://stackoverflow.com/a/36410780/621809

更新:重要说明

我从一些评论和答案中意识到,我在一个方面不够清楚:我不反对使用像 /employees/5 这样的 URL 来处理单个资源/部门/1.我不认为这是嵌套的.

I realize from some of the comments and answers, that I wasn't clear enough regarding one aspect: I'm not against addressing single resources with URLs like /employees/5 or /departments/1. I don't consider that to be nested.

当我说嵌套资源时,我指的是像 /departments/1/employees 这样的 URL,其中资源总是在另一个资源的上下文中寻址.主要问题是对于 URL 构建,通用库需要知道额外的东西,例如员工嵌套在部门下"但分支机构不嵌套在任何东西下".如果所有资源都可以以 REST 方式处理,但以扁平方式处理,那么知道如何处理它们会更简单、更可预测.

When I say nested resources, I refer to URLs like /departments/1/employees where a resource is addressed always within the context of another resource. The main issue is the fact that for URL building, a generic library would need to know extra stuff like "employees are nested under departments" but "branches are not nested under anything". If all resources could be addressed RESTfully, but in a flat fashion, it is simpler and more predictable to know how to address them.

考虑一下,在数据库中,您不需要知道额外的信息来了解如何寻址对象集合(例如 RDMS 中的表).您总是将员工集合称为 employees,而不是 departments/5/employees.

When you think about it, in databases you don't need to know extra information in order to know how to address a collection of objects (e.g. a table in a RDMS). You always refer to the collection of employees as employees, not as departments/5/employees.

推荐答案

如果你想再深入几个级别会怎样?

What happens if you want do drill down a couple more levels?

/api/addresses?departmentId=1&employeeId=2&addressId=3

对比

/api/departments/1/employees/2/addresses/3

Address 端点突然因参数而变得臃肿.

The Address endpoint suddenly becames bloated with parameters.

此外,如果您正在查看 Richardson Maturity Model level 3,RESTfulAPI 旨在通过链接被发现.例如,从顶层,比如/api/version(/1),你会发现有一个指向部门的链接.以下是在 HAL 浏览器等工具中的效果:

Also, if you're looking at the Richardson Maturity Model level 3, RESTful APIs are meant to be discoverable through links. For example, from the top level, say /api/version(/1), you would discover there's a link to the departments. Here's how this could look in a tool like HAL Browser:

"api:department-query": {
  "href": "http://apiname:port/api/departments?pageNumber={pageNumber}&pageSize={pageSize}&sort={sort}"
},
"api:department-by-id": {
  "href": "http://apiname:port/api/departments?departmentId={departmentId}"
}

(可能会以分页方式列出所有内容的查询,或者可以直接转到特定部门的参数化链接,前提是您知道 ID).

(either a query that might list them all, in a paged manner eventually, or a parameterized link that would go directly to a specific department, provided you know the id).

这里的优点是客户端只需要知道关系(链接)名称,而服务器大部分时间可以自由更改关系(和资源)url.

The advantage here would be that the client would only need to know the relationship (link) name, while the server would be mostly free to alter the relationship (and resource) url.

这篇关于RESTful API 路由设计:嵌套与非嵌套的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆