我应该通过 REST API 的路径部分还是查询部分传递变量?
Should I pass variables through the path section or query section of my REST API?
我正在构建一个允许用户管理群组的应用程序。每个组包含 name、campus 和 data type。它们不在任何特定的层次结构中——从语义上讲,一个校区可以被认为有很多组,但也很自然地认为一个组位于层次结构的顶部,分布在许多校区。
name/campus/data_type 的组合是独一无二的
NAME CAMPUS DATA_TYPE
---------------------------------------
LABS WEST IPv4
LABS WEST IPv6
LABS EAST IPv4
USERS NORTH userids
USERS WEST userids
USERS EAST userids
例如,具有 DATA_TYPE IPv4 的西校区 LABS 组将包含与西校区实验室相关的所有 IP 子网。
现在,向下钻取该数据的唯一要求是 group。不需要收集所有 WEST 校园组的列表,例如,或具有 "IPv6" 数据类型的所有组。但是, 需要获取所有拥有 "LABS" 组的校区的列表,并且还需要获取 LABS 的所有 data_types。
那么我应该如何创建端点?
选项 1
长而清晰的 URL。
GET /groups/LABS/ (returns LABS groups across all campuses and data_types)
GET /groups/LABS/data_type/IPv4 (returns all IPv4 LABS groups across all campuses)
GET /groups/LABS/campus/WEST (returns all WEST LABS groups across all data_types)
POST /groups/LABS/campus/NORTH/data_type/IPv4 (create a new group)
POST /groups/LABS/campus/NORTH/data_type/userids (another new group)
优势:
- 避免任何查询参数
缺点:
- 它代表了一个实际不需要的层次结构。
- 还需要app同时支持group->campus->data_type和
组->data_type->校园层次结构。
选项 2
将组视为层次结构的唯一部分,将"campus"和"data_type"视为非层次标识符:
GET /groups/LABS
GET /groups/LABS?campus=WEST
GET /groups/LABS?data_type=IPv4
GET /groups/LABS?campus=WEST&data_type=IPv4
POST /groups/LABS (POST data: {campus: "WEST", data_type: "IPv4})
POST /groups/LABS (POST data: {campus: "WEST", data_type: "IPv4})
优势:
- 似乎体现了"data_types"和"campus"的无等级关系,
并且可以很容易地指定(比如)校园而不用 data_type(或
反之亦然)。
缺点:
- 我不完全确定这是对查询参数的适当使用。
- 此外,它没有为任何人提供非常漂亮的 "permalink"
group/campus/data_type.
的独特组合
我倾向于选项 2。这是表示此数据的最佳方式吗?还是我想错了?
我建议改为支持两个端点。从您的描述中可以清楚地看出,组不是由名称唯一定义的,但您的 URI 结构暗示它是。相反,使用合成 ID 来唯一标识一个组。
GET /groups
?name={}
?campus={}
?data_type={}
<- some collection of all groups that match whichever criteria are specified
POST /groups
-> { "name": "LABS", "campus": "WEST", "data_type": "IPv4" }
GET /groups/{id}
<- { "name": "LABS", "campus": "WEST", "data_type": "IPv4" }
当他们决定添加新的 属性 或想要按 data_type 在所有组中搜索时,这种方法为您提供了更大的灵活性。
您可以在服务器 (meh) 的响应中包含唯一 ID,或者包含超媒体链接以提供有趣的关系,例如具有相同名称或在同一校园内的所有其他组。
我正在构建一个允许用户管理群组的应用程序。每个组包含 name、campus 和 data type。它们不在任何特定的层次结构中——从语义上讲,一个校区可以被认为有很多组,但也很自然地认为一个组位于层次结构的顶部,分布在许多校区。
name/campus/data_type 的组合是独一无二的
NAME CAMPUS DATA_TYPE
---------------------------------------
LABS WEST IPv4
LABS WEST IPv6
LABS EAST IPv4
USERS NORTH userids
USERS WEST userids
USERS EAST userids
例如,具有 DATA_TYPE IPv4 的西校区 LABS 组将包含与西校区实验室相关的所有 IP 子网。
现在,向下钻取该数据的唯一要求是 group。不需要收集所有 WEST 校园组的列表,例如,或具有 "IPv6" 数据类型的所有组。但是, 需要获取所有拥有 "LABS" 组的校区的列表,并且还需要获取 LABS 的所有 data_types。
那么我应该如何创建端点?
选项 1
长而清晰的 URL。
GET /groups/LABS/ (returns LABS groups across all campuses and data_types)
GET /groups/LABS/data_type/IPv4 (returns all IPv4 LABS groups across all campuses)
GET /groups/LABS/campus/WEST (returns all WEST LABS groups across all data_types)
POST /groups/LABS/campus/NORTH/data_type/IPv4 (create a new group)
POST /groups/LABS/campus/NORTH/data_type/userids (another new group)
优势:
- 避免任何查询参数
缺点:
- 它代表了一个实际不需要的层次结构。
- 还需要app同时支持group->campus->data_type和 组->data_type->校园层次结构。
选项 2
将组视为层次结构的唯一部分,将"campus"和"data_type"视为非层次标识符:
GET /groups/LABS
GET /groups/LABS?campus=WEST
GET /groups/LABS?data_type=IPv4
GET /groups/LABS?campus=WEST&data_type=IPv4
POST /groups/LABS (POST data: {campus: "WEST", data_type: "IPv4})
POST /groups/LABS (POST data: {campus: "WEST", data_type: "IPv4})
优势:
- 似乎体现了"data_types"和"campus"的无等级关系, 并且可以很容易地指定(比如)校园而不用 data_type(或 反之亦然)。
缺点:
- 我不完全确定这是对查询参数的适当使用。
- 此外,它没有为任何人提供非常漂亮的 "permalink" group/campus/data_type. 的独特组合
我倾向于选项 2。这是表示此数据的最佳方式吗?还是我想错了?
我建议改为支持两个端点。从您的描述中可以清楚地看出,组不是由名称唯一定义的,但您的 URI 结构暗示它是。相反,使用合成 ID 来唯一标识一个组。
GET /groups
?name={}
?campus={}
?data_type={}
<- some collection of all groups that match whichever criteria are specified
POST /groups
-> { "name": "LABS", "campus": "WEST", "data_type": "IPv4" }
GET /groups/{id}
<- { "name": "LABS", "campus": "WEST", "data_type": "IPv4" }
当他们决定添加新的 属性 或想要按 data_type 在所有组中搜索时,这种方法为您提供了更大的灵活性。
您可以在服务器 (meh) 的响应中包含唯一 ID,或者包含超媒体链接以提供有趣的关系,例如具有相同名称或在同一校园内的所有其他组。