我寻求有关设计API端点的建议。
我有一个ID为(PK)的表(资源)和一些其他ID,它们不是唯一的,但没有空约束。
现在设计:
/<resourceName>/{id}
非PK搜索
2.1 /<resourceName>/someOtherIdName/{someOtherId}
-使用路径参数,对于不同的ID是不同的
2.2或/<resourceName>?<nameOfId>=<value>
-使用查询参数
对于第二种方法,哪种方法更好?如果我使用2.2,则可以支持多个ID,但是由于我必须检查nameOfId
,所以它变得令人费解。那2.1呢?
编辑:例如,以transactions
作为资源,以txn_id
作为主键,以txn_event_id
和txn_activity_id
作为其他键ID。最后两个ID可以代表一组相关的交易。 2.2是否适合最后两个ID?
在2.1的情况下,实现如下所示:
@Path("/transactions")
class TransactionResource {
@Path("/eventid/{event_id}")
public List getTxnWithEventId(@PathParam("event_id") String eventId) {
// do a "event_id" based search
}
@Path("/activityid/{activity_id}")
public List getTxnWithActivityId(@PathParam("activity_id") String txnActivityId) {
// do a "pin" based search
}
}
在2.2的情况下,实现类似于:
@Path("/transactions")
class TransactionResource {
public List getTxnsWithAnotherId(@QueryParam("searchKey") String id,
@QueryParam("searchValue") String value) {
if("event_id".equals(id)) // do a "event_id" based search
else if("activity_id".equals(id)) // do a "activity_id" based search
else return null;
}
}
我认为第二个选项对于搜索而言感觉更好,但如果是这样,为什么不选择第二个呢?
答案 0 :(得分:0)
我认为一切都取决于开发人员的偏好。我不会使用您列出的任何一个选项。我的方法是collectionId/resourceId/collectionId/resourceId
。因此,在您的情况下,将获得users/1/messages
特定用户的所有消息,例如users/1/messages/1
,以获取该特定用户的ID为1的消息。这样,您可以创建更清晰的API终结点,这些终结点可以在您的应用中更有效地路由,并且可以得到更好的文档编制和管理。
看看Google's API Design Guide如何针对其Gmail资源模型来解决这个问题:
A collection of users: users/*. Each user has the following resources.
A collection of messages: users/*/messages/*.
A collection of threads: users/*/threads/*.
A collection of labels: users/*/labels/*.
A collection of change history: users/*/history/*.
A resource representing the user profile: users/*/profile.
A resource representing user settings: users/*/settings.
答案 1 :(得分:0)
对于第二个,哪种方法更好?
对于大多数用例,这两种方法都很好
/<resourceName>?<nameOfId>=<value>
/<resourceName>/<nameOfId>/<value>
西红柿,番茄。
您可能会关心差异的一个原因是相对分辨率和dot segments的使用。点段对于遍历URI的层次结构部分(即路径段)很有用。
您可能会关心的另一个原因是URI的query part并不总是被理解为标识符的一部分。 HTTP规范的Old versions描述了当存在查询部分时缓存规则的例外。在the current standard中,这没有什么不同。
如果您在将URI的可读性与编码到路径段中的数据作斗争时遇到了麻烦,那么有许多拼写约定可能会有所帮助-许多都是从TBL在Matrix URI上的工作中得出的。如果您的客户端和服务器可以访问不错的URI Template实现,那么您已经完成了很多工作。
答案 2 :(得分:-1)
我不确定您的资源具体是什么,但是这里是设计RESTful API时要记住的一些提示
标识什么是主要资源。 例如:员工
在第一种情况下,您将以
的身份访问员工GET /employees
。获取所有员工。GET /employees/1
。获取ID为1的特定员工。搜索特定于您的需求。如果您需要根据ID提取多名员工,则可以
GET /employees?id=1,2,3,4
或者,如果您发现需要基于多个参数进行搜索,则建议您使用POST
POST /employees/search
{
id: [1,2,3,4],
department: "computer-science"
}