多个ID的Rest API资源命名

7

阅读完后:

https://restfulapi.net/resource-naming/

我有一个问题,关于在文档具有多个唯一标识时如何在集合中引用文档。

在链接的文章中,给出了一个示例:

我们可以使用URI“/customers/{customerId}”来识别单个“customer”资源。

或者

http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin

我的例子:

http://myserver/api/courses/{id}

这个功能有一个相应的JS Express函数:

app.get('/api/courses/:id', (req, res) =>... 

我的问题是,如果我的文档(课程)有两个唯一的ID键(如ID1和ID2),我该如何保持一致的API?在express中怎样编写代码?怎么写URL?
那么,如果我需要这两个API分别为:
http://myserver/api/courses/{id1}
http://myserver/api/courses/{id2}

如果我提供了两个Express例程:
app.get('/api/courses/:id1', (req, res) =>... 
app.get('/api/courses/:id2', (req, res) =>... 

如果ID1和ID2都是相同类型的(例如数字),REST API如何区分这两个ID?


你能告诉我们为什么你有这些不同的ID吗?它们与外部世界有关吗?如果没有,你可以只使用一个ID。 - Kryptur
@charlietfl 这不是真的。一个元素可以有多个唯一的ID - 每个ID在一个明确定义的范围内都是唯一的。 - Kryptur
我很想知道你是如何存储课程的,以及如何在数据库中查询它?如果以相同的方式查找,那么您仍将只使用单个路由,例如/api/courses/1234/api/courses/5678可以引用相同的课程,但仍然使用相同的API。 - James
许多国家的课程/产品都有本地ID和国际ID。库存系统一直在这样做!卖方零件号,供应商零件号。两者都是独特的,而且很多时候不同! - Walter ZAMBOTTI
3个回答

3

REST对于您的资源标识符的拼写并不关心。类似于代码约定中有关拼写变量名称的约定,如https://restfulapi.net/resource-naming/所描述的约定。

从REST客户端的角度来看,/api/courses/X/api/courses/Y是不同的资源--这些资源可能共享相同的基础表示(因为它们是从相同的基础数据构建而成),但这是服务器的实现问题。

URI的拼写仅受RFC 3986的限制。

/api/courses?id1=12345
/api/courses?id2=67890

这是一个完全合理的选择。其中一个潜在的好处是,HTML包括使用查询参数创建URI模板的标准。一个潜在的缺点是,相对引用解析将查询部分非分层数据与路径段中的分层数据处理方式不同。

/api/courses/id1/12345
/api/courses/id2/67890

这是一个非常合理的选择,与上述选择相反,但也有其权衡之处。

/api/courses/id1=12345
/api/courses/id2=67890

这实际上是与上文相同的思路,只是拼写略有不同。它具有易于理解和人类可读性的优点。但是,实际上使用该模式可能会很具有挑战性,具体取决于您拥有哪种类型的路由支持。

作为URI模板,它们可能看起来像:

/api/courses/id1={id}
/api/courses/id2={id}

但是在支持级别4 URI模板的地方,您可能可以使用

 /api/courses/{/ids*}

另一个可能性是使用基于“矩阵参数”的拼写方法,例如:

/api/courses;id1=12345
/api/courses;id2=67890

同样,这给您提供了一组不同的权衡方案,包括可读性、模板支持、相对分辨率支持等等。

另请参阅Stefan Tilkov -- REST:我认为它并不是你想象中的那样


REST API的命名规范与express确定路由的方式不同。根据OP编写的路由,express将无法区分这些路由。Express会将路由存储在一个堆栈中,并匹配先声明的路由(id1)。id1只是一个名称,代表通用数据(如作用域变量)。 - MisterSnow

1
你需要在url中进行另一种区分,可以是路径或查询参数方式来知道哪个字段正在被发送。默认情况下,一个字段为#1,另一个字段为#2。
app.get('/api/courses/:id1', (req, res) =>... 
app.get('/api/courses/other-key/:id2', (req, res) =>...

0
REST API的命名规范与Express的确定方式不同。根据OP编写路由的方式,Express将无法区分这些路由。Express将路由存储在堆栈中,并将其与先声明的路由(id1)匹配。id1仅是表示通用数据(如作用域变量)的名称。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接