有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring REST URI存在性检查

让我们假设一个简单的基于Spring的RESTful API,其中包含一些嵌套资源

  • AUser是由每个人创建的用于访问API的根实体
  • 每个User都可以创建Posts,因此没有创建者Post就不可能存在
  • AUser还可以注释现有的Posts,因此AComment属于APost

对于此API,我选择了以下RESTful路由:

  • /api/users用于User
  • /api/users/{userId}/posts代表Post
  • /api/users/{userId}/posts/{postId}/comments用于{}

关于我的问题,我是否应该验证父资源是否存在?例如,对于请求GET /api/users/2/posts/3/comments/7,我是否应该确保实体User(2)Post(3)也存在?我是否还必须确保实体彼此相关,并且不使用任何现有的x任意资源

示例

@PostMapping("/api/users/{userId}/posts/{postId}/comments")
public void create(@PathVariable("userId") Long userId, @PathVariable("postId") Long postId, @RequestBody CommentPayload payload) {

    // userService.existsByIdWithPostId(userId, postId); ???

    commentService.createForPost(postId, payload);
}

要在数据库中创建注释,userId是完全不相关的,只需要postId。我应该仍然确保具有userIdX的用户存在,并且具有具有postIdY的帖子,还是应该忽略它

如果是,我如何才能做到这一点?因为像Optional<Comment> findByUserIdAndPostIdAndId(...)这样不断增长的JPA/存储库查询似乎不是一个解决方案。。。验证是否应该在几个查询中进行?包含所有父ID会使实际查询复杂化。此外,标识符必须通过所有层(服务层、安全层)传递,这使内部API变得复杂


共 (1) 个答案

  1. # 1 楼答案

    简短回答:是的,您必须检查父/根实体是否存在,是的,您需要定义实体之间的关系

    答案很长:

    没有用户就无法创建帖子,这一事实不必通过URL结构进行检查。URL仅用于澄清所请求的资源。检查必须直接在代码中完成。检查记录的存在不需要额外的工作和方法,这是因为实体之间的关系

    当您使用/users/{userId}/postsAPI为用户添加帖子时,需要使用id=[userId]将帖子添加到用户的帖子列表中,因此您调用相关的存储库方法来获取用户记录(如findById),这本身就是使用id=[userId]检查用户是否存在的行为。因为如果存储库返回null,您就知道用户不存在

    要设计好的、高效的、可理解的API,请遵循以下简单规则:

    如果资源可以单独访问,那么它必须有一个基本URL作为/[entity],否则使用父子模式(就像您的帖子一样)

    请注意,此规则不能一直有效,很多时候您需要自定义API并将其更改为更高效

    因此,如果用户可以看到其他用户的帖子,那么您应该设计如下API:

    • /users[对用户实体的请求]
    • /posts[请求发布实体]

    然后,对于针对特定用户帖子的请求,您应该使用/users/{userId}/posts来创建新帖子或阅读它们,对于针对特定帖子评论的请求,您应该使用/posts/{postId}/comments

    据我所知,你的应用程序的设计不需要/comments,因为所有评论都与帖子相关,应该由相关帖子访问(如上所述)。如果评论可以单独访问(比如有一个页面列出所有评论,而不关心它们的相关帖子),那么您需要/commentsAPI来进行更多的澄清