Spring 引导 REST 路径映射
Spring Boot REST path mapping
我只是在想,为 rest 服务创建 PATH 映射的最佳实践是什么。
假设我们有以下路径:
/users POST
/users/1 PATCH, GET
/users/1/contacts GET, POST
/users/1/contacts/1 GET, PATCH
问题是 - 创建控制器的最佳做法是什么。
例如,我们有 UserController,技术上我们可以在其中放置所有这些映射。或者 - 我们应该创建单独的控制器(UserController,
联系人控制器)。
f.e下面的UserController,如果我们把所有东西都放在下面。
@RequestMapping("users")
@RestController
public class UserController {
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Void> createUser() {}
@RequestMapping(method = RequestMethod.GET)
public User getUser() {}
@RequestMapping(value = "{id}/contacts", method = RequestMethod.GET)
public List<Contact> getContacts() {}
@RequestMapping(value = "{id}/contacts", method = RequestMethod.POST)
public ResponseEntity<Void> createContact() {}
.....
}
如果我们创建单独的控制器,那么应该如何组织路径?
可能这是一个愚蠢的问题,但如果有人可以分享经验,我会很高兴。
让我们建议将来与用户相关的实体数量会增加。所以很明显,最好根据实体拆分它:
UserController -> UserService -> UserRepository,
ContactController -> ContactService -> ContactRepository,
FriendshipController -> FriendshipService -> FriendshipRepository
根据我的经验,用户控制器
@RestController
@RequestMapping("/user")
public class UserController extends AbstractController {
...
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createUser(@RequestHeader("X-Auth-Token") Optional<String> @RequestBody User user) {
...
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<?> listUsers(@RequestHeader("X-Auth-Token") Optional<String> authToken) {
...
与用户范围相关 友情管理员:
@RestController
@RequestMapping("/user/{id}")
public class FriendshipController extends AbstractController {
...
@RequestMapping(value = "/friendship/code", method = RequestMethod.POST)
public ResponseEntity<?> generateCodeForUser(@PathVariable("id") long id) {
...
@RequestMapping(value = "/friendship/code", method = RequestMethod.GET)
public ResponseEntity<?> retrieveCodeForUser(@PathVariable("id") long id) {
...
不确定这是公理,但帮我整理一下代码。
我是独立控制器的粉丝,因为它们消除了 Users
和 Contacts
之间的耦合(例如)——如果稍后您想在单独的上下文中使用 Contacts
怎么办? (即独立于他们所属的User
)
如果将它们分开,路径将与您的路径非常相似:
用户
/users GET, POST
/users/{user-id} PATCH, GET
联系人
/contacts GET, POST
/contacts/{contact-id} GET, PATCH
如果 Contacts
和 Users
之间存在依赖关系(在这种情况下,看起来有一个),你可以这样:
/contacts/for-user/{user-id} GET, POST
/contacts/for-user/{user-id}/{contact-id} GET, PATCH
这允许您将联系人添加到其他事物(不仅仅是用户)和用户到其他上下文(不管他们的联系人)
例如,咖啡机用户
/coffee-maker/users GET
或者如果咖啡机出现故障,我们找谁维修?
/coffee-maker/contacts GET
咖啡机维修联系人可能也是用户(但不一定是)
还有一件事,你可以反过来说一个触点是一个电器(即咖啡机)
/contact/for-appliance/{appliance-id} GET
我的观点是,如果您将联系人与用户分离,您可以将联系人分配给其他实体,而不是强制关系成为 User -> Contacts
- 当然,除非您不想分离他们因为业务规则或某些原因
无论如何,请注意有很多方法可以进行映射
我只是在想,为 rest 服务创建 PATH 映射的最佳实践是什么。 假设我们有以下路径:
/users POST
/users/1 PATCH, GET
/users/1/contacts GET, POST
/users/1/contacts/1 GET, PATCH
问题是 - 创建控制器的最佳做法是什么。 例如,我们有 UserController,技术上我们可以在其中放置所有这些映射。或者 - 我们应该创建单独的控制器(UserController, 联系人控制器)。 f.e下面的UserController,如果我们把所有东西都放在下面。
@RequestMapping("users")
@RestController
public class UserController {
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Void> createUser() {}
@RequestMapping(method = RequestMethod.GET)
public User getUser() {}
@RequestMapping(value = "{id}/contacts", method = RequestMethod.GET)
public List<Contact> getContacts() {}
@RequestMapping(value = "{id}/contacts", method = RequestMethod.POST)
public ResponseEntity<Void> createContact() {}
.....
}
如果我们创建单独的控制器,那么应该如何组织路径? 可能这是一个愚蠢的问题,但如果有人可以分享经验,我会很高兴。
让我们建议将来与用户相关的实体数量会增加。所以很明显,最好根据实体拆分它:
UserController -> UserService -> UserRepository,
ContactController -> ContactService -> ContactRepository,
FriendshipController -> FriendshipService -> FriendshipRepository
根据我的经验,用户控制器
@RestController
@RequestMapping("/user")
public class UserController extends AbstractController {
...
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createUser(@RequestHeader("X-Auth-Token") Optional<String> @RequestBody User user) {
...
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<?> listUsers(@RequestHeader("X-Auth-Token") Optional<String> authToken) {
...
与用户范围相关 友情管理员:
@RestController
@RequestMapping("/user/{id}")
public class FriendshipController extends AbstractController {
...
@RequestMapping(value = "/friendship/code", method = RequestMethod.POST)
public ResponseEntity<?> generateCodeForUser(@PathVariable("id") long id) {
...
@RequestMapping(value = "/friendship/code", method = RequestMethod.GET)
public ResponseEntity<?> retrieveCodeForUser(@PathVariable("id") long id) {
...
不确定这是公理,但帮我整理一下代码。
我是独立控制器的粉丝,因为它们消除了 Users
和 Contacts
之间的耦合(例如)——如果稍后您想在单独的上下文中使用 Contacts
怎么办? (即独立于他们所属的User
)
如果将它们分开,路径将与您的路径非常相似:
用户
/users GET, POST
/users/{user-id} PATCH, GET
联系人
/contacts GET, POST
/contacts/{contact-id} GET, PATCH
如果 Contacts
和 Users
之间存在依赖关系(在这种情况下,看起来有一个),你可以这样:
/contacts/for-user/{user-id} GET, POST
/contacts/for-user/{user-id}/{contact-id} GET, PATCH
这允许您将联系人添加到其他事物(不仅仅是用户)和用户到其他上下文(不管他们的联系人)
例如,咖啡机用户
/coffee-maker/users GET
或者如果咖啡机出现故障,我们找谁维修?
/coffee-maker/contacts GET
咖啡机维修联系人可能也是用户(但不一定是)
还有一件事,你可以反过来说一个触点是一个电器(即咖啡机)
/contact/for-appliance/{appliance-id} GET
我的观点是,如果您将联系人与用户分离,您可以将联系人分配给其他实体,而不是强制关系成为 User -> Contacts
- 当然,除非您不想分离他们因为业务规则或某些原因
无论如何,请注意有很多方法可以进行映射