如何最好地构建 RESTful API 端点

How best to structure a RESTful API Endpoint

我正在努力将我的应用程序从紧密耦合的 PHP 实现过渡到 RESTful 实现。 (当前应用在 http://coinvault.tanichols.com

该应用维护硬币(州 25 美分硬币、总统美元等)和用户的集合。用户也可以'collect'一个硬币,表示为用户和硬币tables之间的多对多关系。

我创建了以下 table 动词和端点组合:

GET    /coins               - Get all coins 
POST   /coins               - Create a new coin
GET    /coins/CID           - Get a coin
PUT    /coins/CID           - Update a coin 
DELETE /coins/CID           - Delete a coin

GET    /users               - Get all users
POST   /users               - Create a new user
GET    /users/UID           - Get a user
PUT    /users/UID           - Update a user
DELETE /users/UID           - Delete a user

我遇到的麻烦是 proper/accepted 从许多 table 中公开信息的方式。例如,我可以使用以下一组路由:

GET    /users/UID/coins     - Get coins for a user
POST   /users/UID/coins     - Create a coin for a user
GET    /users/UID/coins/CID - Get a specific coin for a user
PUT    /users/UID/coins/CID - Update a specific coin for a user
DELETE /users/UID/coins/CID - Delete a specific coin for a user

或者我可以将其转换为:

GET    /coins/CID/users/UID - Get a specific coin for a user
PUT    /coins/CID/users/UID - Update a specific coin for a user
DELETE /coins/CID/users/UID - Delete a specific coin for a user

Q1:其中一个比另一个更受欢迎吗?是否有标准或公认的方式来规划这些类型的路线?

我还可以使用以下路由和过滤器公开此功能:

GET    /coins?user_id=1     - Get all coins belonging to a user

问题 2: 这种方法是更好还是更糟?这是否会向 /coins 路由添加不必要的 'weight'?

最后,在这种情况下,我想提供对某些聚合的访问,例如收集特定硬币的次数,以用于报告和分析目的。对于这个,我完全不知道从哪里开始,或者如何解决这个问题。

Q3: 如何通过 RESTful API 公开此类聚合?对此有意义的路线是什么?

Q1:

您表示集合和项目的方式绝对有效,但您的第一个提案在您的上下文中有效:

GET    /users/UID/coins     - Get coins for a user
POST   /users/UID/coins     - Create a coin for a user
GET    /users/UID/coins/CID - Get a specific coin for a user
PUT    /users/UID/coins/CID - Update a specific coin for a user
DELETE /users/UID/coins/CID - Delete a specific coin for a user

如果某物属于某人,则用 /someones/SID/things/TID 表示。

Q2:

本提案:

GET    /coins?user_id=1     - Get all coins belonging to a user

绝对不是一个好主意,它违背了 REST 最佳实践。

Q3:

这不是聚合的问题,这些数据是绑定到一个硬币上的,因此你可以简单地return它们在GET /coins/CID的数据中。 将端点相乘绝对不是一个好主意,尤其是如果始终需要这些数据。