在Spring(“REST”)控制器中处理关系
我目前正在开发一个具有多个模型对象的应用程序,这些模型对象之间有很多关系 例如,我有一个用户对象和一个组对象,其中有多个用户 我们为这些对象公开的端点是:在Spring(“REST”)控制器中处理关系,spring,rest,spring-mvc,spring-boot,spring-rest,Spring,Rest,Spring Mvc,Spring Boot,Spring Rest,我目前正在开发一个具有多个模型对象的应用程序,这些模型对象之间有很多关系 例如,我有一个用户对象和一个组对象,其中有多个用户 我们为这些对象公开的端点是: /users /users/{uid} /users/{uid}/groups /users/{uid}/groups/{gid} /groups /groups/{gid} /groups/{gid}/users /groups/{gid}/users/{uid} 到目前为止,这很容易。现在让我们假设每个用户和每个组都可以有设置、消息、
/users
/users/{uid}
/users/{uid}/groups
/users/{uid}/groups/{gid}
/groups
/groups/{gid}
/groups/{gid}/users
/groups/{gid}/users/{uid}
到目前为止,这很容易。现在让我们假设每个用户和每个组都可以有设置、消息、化身等等
现在我们可以公开端点,例如
/users/{uid}/avatar
/groups/{uid}/avatar
/users/{uid}/messages
/users/{uid}/messages/{mid}
/groups/{gid}/messages
/groups/{gid}/messages/{mid}
/users/{uid}/settings
/groups/{gid}/settings
即使只有6个关系(用户->化身,组->化身,用户->消息,组->消息,用户->设置,组->设置),当我们考虑各种CRUD操作(放置,删除,POST,GET,…)/P>时,请求映射的数量(端点)都会大大增加。 如果我添加另一个资源,例如可以包含多个组的groupOfGroups,那么我将公开的RequestMappings的数量将成倍增加
/gog/{gogid}/groups
/gog/{gogid}/groups/{gid}
/gog/{gogid}/groups/{gid}/users
/gog/{gogid}/groups/{gid}/users/{uid}
/gog/{gogid}/settings
/gog/{gogid}/messages
/gog/{gogid}/avatar
我还将为CRUD操作添加RequestMappings
为了避免代码重复,我在每个主控制器中都使用了catch-all请求映射。例如,在UserController中,我将有以下requestMappings
GET /users
GET /users/{id}
POST /users
PUT /users/{id}
DELETE /users/{id}
/**
/**映射将捕获/users/{uid}/messages/{mid}调用。在/**映射对应的方法中,我将执行以下操作
/users/{uid}/messages
/users/{uid}/settings
/users/{uid}/avatar
检查用户是否存在,这将对groups和groupOfGroups执行相同的功能,但唯一的区别是我们正在检查该组是否存在或groupOfGroups是否存在
需要注意的是,像Swagger这样的工具当然不支持这种方法,甚至向前看,也不能使用@RestController,只能使用更通用的web mvc注释@Controller
我想知道这里最好的方法是什么。在我看来,您试图在URI路径中表示关系(或者也可能是导航)。REST中的关系表示为链接,来自: 可以说一个团队有一个文档资源(/team/{id}/players),它是指向团队中的玩家(/player/{id})的链接列表,玩家可以有一个文档资源(/player/{id}/teams),它是指向该玩家所属团队的链接列表 REST与URI的外观无关,更多的是向客户端发送指向特定状态下可用操作的链接(例如:如果我在
/users/1
中,我可以转到/users/1/messages
)。只要服务器构建链接,客户端只使用它们,链接的结构就无关紧要
但是,您的一些URI包含了他们需要的更多信息(并且可能需要URI构建(而不是rest)客户端了解它不需要知道的事情):/gog/{gogid}/groups/{gid}/users/{uid}
和/groups/{gid}/users/{uid}
与/users/{uid}
因为用户的数据总是可以由{uid}
检索
另一种可能性是/groups/{gid}/users/{uid}
实际上意味着“表示用户和组之间关联的资源”例如,包括用户加入组的日期;如果是这种情况,那么对我来说这是一个新资源,例如:成员身份
,具有自己的ID,可以映射到/membership/{membership ID}
,并且/groups/{gid}/users/{uid}
可以重定向到它。成员身份将在/groups/{gid}中列出/会员资格
/users/{uid}/avatar
和/groups/{gid}/avatar
可以重定向到他们的/avatar/{avatar id}
。如果共享了avatar,那么在使用HTTP缓存时这可能会有好处。在我看来,你是在试图表示关系(或者可能也是导航)在URI路径中。REST中的关系表示为链接,来自:
可以说一个团队有一个文档资源(/team/{id}/players),它是指向团队中的玩家(/player/{id})的链接列表,玩家可以有一个文档资源(/player/{id}/teams),它是指向该玩家所属团队的链接列表
REST与URI的外观无关,更多的是向客户端发送指向特定状态下可用操作的链接(例如:如果我在/users/1
中,我可以转到/users/1/messages
)。只要服务器构建链接,客户端只使用它们,链接的结构就无关紧要
但是,您的一些URI包含了他们需要的更多信息(并且可能需要URI构建(而不是rest)客户端了解它不需要知道的事情):/gog/{gogid}/groups/{gid}/users/{uid}
和/groups/{gid}/users/{uid}
与/users/{uid}
因为用户的数据总是可以由{uid}
检索
另一种可能性是,/groups/{gid}/users/{uid}
实际上意味着“一个资源,表示一个用户之间的关联