Spring REST 重用嵌套请求映射
Spring REST reuse nested requstmapping
我们有一个 REST API,用于一些评论。目前,最有趣的 URI 是:
GET /products/1/comments // get all comments of product 1
GET /products/1/comments/5 // get the 5th comment of product 1
GET /products/1/comments/5/user // get the user of the 5th comment
GET /products/1/comments/latest // get the latest comment of product 1
GET /products/1/comments/latest/user // get the user of the latest comment
此外,您可以直接访问评论
GET /comments/987 // get the comment with id 987
GET /comments/987/user // get the user of comment with id 987
所以,我们有两个 @RestController
:
@RestController
@RequestMapping("/products/{productId}")
public class ProductsCommentsResource {
@GetMapping(value = "/comments")
public ResponseEntity<?> getComments(@PathVariable Long productId){
// get all products...
}
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
@GetMapping(value = "/comments/{commentNr}/user")
public ResponseEntity<?> getCommentUser(@PathVariable Long productId, @PathVaraible Long commentNr){
// get the user of comment with commentNr of productId
}
@GetMapping(value = "/comments/latest")
public ResponseEntity<?> getLatestComment(@PathVariable Long productId){
// get latest commentNr and call getComment(productId, commentNr)
}
@GetMapping(value = "/comments/latest/user")
public ResponseEntity<?> getLatestCommentUser(@PathVariable Long productId){
// get latest commentNr and call getCommentUser(productId, commentNr)
}
}
@RestController
@RequestMapping("/comments")
public class CommentsResource {
@GetMapping(value = "/{commentId}")
public ResponseEntity<?> getComment(@PathVaraible Long commentId){
// get comment id commentId
}
@GetMapping(value = "/{commentId}/user")
public ResponseEntity<?> getCommentUser(@PathVaraible Long commendId){
// get the user of comment with id commentId
}
}
因此 latest
只是 "get the last commentNr and call the corresponding method with this commentId"
的替换关键字
这只是一个摘录,除了用户,一条评论还有大约30个子资源和子资源(包括方法POST、DELETE等)。
因此,我们或多或少拥有三倍的一切。
所以,很明显,我们需要改进这一点,删除重复代码等。
这个想法是 "encapsulate" 评论资源,并通过使用 class 注释的 @RequestMapping
使其可重用。
我们考虑了这样一种机制:
/products/1/comments/latest/user
被称为
- 调用被拦截,商品1的"latest"解析为commentId
- 调用将重定向到```/comments/{commendId}/user
因此,我们需要一些可以重定向的东西
- /products/1/comments/latest[what ever]
至 /comments/{commentId}[what ever]
- /products/1/comments/5[what ever]
也 /comments/{commentId}[what ever]
and /comments/{commentId} 将是唯一的实现。
但是,我们在 spring 文档中没有找到合适的内容...
您可以在控制器的 @RequestMapping
中添加额外的 URL 路径前缀。
@RequestMapping(value = { "/products/{productId}", "/" })
这意味着您可以删除 CommentsResource
控制器,然后您将能够访问位于以下位置的相同资源:
/products/1/comments/5
在
/comments/5
例如,这里:
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
明显的问题是 productId
路径变量。如果您使用的是 Java 8,可以使用 Optional
:
轻松解决
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Optional<Long> productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
// Check whether productId exists
}
我们有一个 REST API,用于一些评论。目前,最有趣的 URI 是:
GET /products/1/comments // get all comments of product 1
GET /products/1/comments/5 // get the 5th comment of product 1
GET /products/1/comments/5/user // get the user of the 5th comment
GET /products/1/comments/latest // get the latest comment of product 1
GET /products/1/comments/latest/user // get the user of the latest comment
此外,您可以直接访问评论
GET /comments/987 // get the comment with id 987
GET /comments/987/user // get the user of comment with id 987
所以,我们有两个 @RestController
:
@RestController
@RequestMapping("/products/{productId}")
public class ProductsCommentsResource {
@GetMapping(value = "/comments")
public ResponseEntity<?> getComments(@PathVariable Long productId){
// get all products...
}
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
@GetMapping(value = "/comments/{commentNr}/user")
public ResponseEntity<?> getCommentUser(@PathVariable Long productId, @PathVaraible Long commentNr){
// get the user of comment with commentNr of productId
}
@GetMapping(value = "/comments/latest")
public ResponseEntity<?> getLatestComment(@PathVariable Long productId){
// get latest commentNr and call getComment(productId, commentNr)
}
@GetMapping(value = "/comments/latest/user")
public ResponseEntity<?> getLatestCommentUser(@PathVariable Long productId){
// get latest commentNr and call getCommentUser(productId, commentNr)
}
}
@RestController
@RequestMapping("/comments")
public class CommentsResource {
@GetMapping(value = "/{commentId}")
public ResponseEntity<?> getComment(@PathVaraible Long commentId){
// get comment id commentId
}
@GetMapping(value = "/{commentId}/user")
public ResponseEntity<?> getCommentUser(@PathVaraible Long commendId){
// get the user of comment with id commentId
}
}
因此 latest
只是 "get the last commentNr and call the corresponding method with this commentId"
这只是一个摘录,除了用户,一条评论还有大约30个子资源和子资源(包括方法POST、DELETE等)。 因此,我们或多或少拥有三倍的一切。
所以,很明显,我们需要改进这一点,删除重复代码等。
这个想法是 "encapsulate" 评论资源,并通过使用 class 注释的 @RequestMapping
使其可重用。
我们考虑了这样一种机制:
/products/1/comments/latest/user
被称为- 调用被拦截,商品1的"latest"解析为commentId
- 调用将重定向到```/comments/{commendId}/user
因此,我们需要一些可以重定向的东西
- /products/1/comments/latest[what ever]
至 /comments/{commentId}[what ever]
- /products/1/comments/5[what ever]
也 /comments/{commentId}[what ever]
and /comments/{commentId} 将是唯一的实现。
但是,我们在 spring 文档中没有找到合适的内容...
您可以在控制器的 @RequestMapping
中添加额外的 URL 路径前缀。
@RequestMapping(value = { "/products/{productId}", "/" })
这意味着您可以删除 CommentsResource
控制器,然后您将能够访问位于以下位置的相同资源:
/products/1/comments/5
在
/comments/5
例如,这里:
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Long productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
}
明显的问题是 productId
路径变量。如果您使用的是 Java 8,可以使用 Optional
:
@GetMapping(value = "/comments/{commentNr}")
public ResponseEntity<?> getComment(@PathVariable Optional<Long> productId, @PathVaraible Long commentNr){
// get comment with number commentNr of product productId
// Check whether productId exists
}