Java RestController设计-Spring引导REST API
我对restapi开发非常陌生。我已经决定使用SpringBoot创建一个博客应用程序,我真的在为我的应用程序的设计和结构而挣扎 现在,我的应用程序由帖子和评论模型以及存储库组成。对于这两种模型,我都创建了服务类(PostService和CommentService)。在这些类中,我拥有所有的业务逻辑(现在只是简单的CRUD) 现在,我对我的@RestControler帖子的设计摸不着头脑。在PostController中,我公开了以下操作:Java RestController设计-Spring引导REST API,java,spring,spring-boot,rest,Java,Spring,Spring Boot,Rest,我对restapi开发非常陌生。我已经决定使用SpringBoot创建一个博客应用程序,我真的在为我的应用程序的设计和结构而挣扎 现在,我的应用程序由帖子和评论模型以及存储库组成。对于这两种模型,我都创建了服务类(PostService和CommentService)。在这些类中,我拥有所有的业务逻辑(现在只是简单的CRUD) 现在,我对我的@RestControler帖子的设计摸不着头脑。在PostController中,我公开了以下操作: @PostMapping(“/api/posts/c
@PostMapping(“/api/posts/create”)
公共帖子创建(@RequestBody Post){…}
@GetMapping(“/api/posts”)
公共列表findAll(){…}
@GetMapping(“/api/posts/{id}”)
public Post findById(@PathVariable(“id”)Long id){…}
@PutMapping(“/api/posts/{id}”)
公共帖子更新(@RequestBody Post){…}
@DeleteMapping(“/api/posts/{id}”)
public void delete(@PathVariable Long id){…}
现在我开始问我的问题。我想知道在帖子中添加评论的正确设计是什么
addComment
添加到PostController以创建新注释汤姆老实说,我认为这里没有人能给你一个完美的答案。这通常是个人的决定。通常,您可以对RESTAPI说以下几点
- 路径应仅表示数据库中的数据结构。例如
/api/posts
- 在你的道路上没有动词您想做的事情应该由RequestType(GET、POST、PUT、PATCH、DELETE等)处理
评论总是帖子的一部分,正因为如此
您可以这样设计API
@PostMapping("/api/posts/{id}/comment")
public Comment create(@PathVariable Long id), @RequestBody Comment comment) { ... }
Comment
作为自己的对象处理,而Post
只是您通过属性添加到其中的一个关系
@PostMapping("/api/comments")
public Comment create(@RequestBody Comment comment) { ... }
/API/object/xxx/yyy
更新
在阅读了@gulliva的评论之后,我认为还有一个好方法,就是使用这个URL
@PostMapping(“/api/posts/{id}/comment”)
,但将它放在评论控件中。我认为这是一个很好的方法。 < P>如果我是你,我会从REST中考虑REST设计原则,并遵循<代码>资源>子资源->方法>标识符< /代码>模式。从可读性和理解性的角度来看,这可能是最简洁明了的设计
@PostMapping("/api/posts/") //you don't need /create as a separate URI
public Post create(@RequestBody Post post) { ... }
@GetMapping("/api/posts") //This is OK.
public List<Post> findAll() { ... }
@GetMapping("/api/posts/{id}") //OK, however {id} should be optional, hence you can combine this and upper methods in one method.
public Post findById(@PathVariable("id") Long id) { ... }
@PutMapping("/api/posts/{id}") //OK.
public Post update(@RequestBody Post post) { ... }
@DeleteMapping("/api/posts/{id}") //OK.
public void delete(@PathVariable Long id) { ... }
等等。我希望你能想出方法签名和其他方法映射
您还可以看到RESTful命名约定您的api看起来不错!您可以从/api/posts/create中删除create,因为POST请求仍然意味着您要创建一个POST。要添加注释,您可以添加一个CommentController,该控制器依赖于您的两个服务(PostService和CommentService)。URL可能类似于/api/posts/{id}/comment。看看这个,创建一个新的控制器来处理注释功能。将它们放在同一个控制器中会使该控制器变得麻烦,因为您将不得不在某个时候向评论部分添加其他功能。谢谢大家。。。。只有一个问题。因为没有post就有评论是没有意义的,所以在CommentController:@PostMapping(“/api/post/{id}/commets”)中使用这样的URL作为create方法是否正确?非常感谢您的回答。可以向我解释一下为什么要将注释方法保存在PostController中吗?@TomášNa'viKoválik不是方法本身,而是posts URI下的资源路径URI。从表现的角度思考。如果没有父资源,评论本身是不存在的,对吗?因此,当您将API公开给第三方世界时,单独处理评论将不是直观和可理解的设计。此外,如果您要为GET和POST创建两个离散的uri(正如公认的答案所建议的),这也将违反DRY原则。。你只需要复制,这是不好的。好吧,现在对我来说更有意义了。还有一个问题:如果我将来决定不仅仅在帖子中使用注释,那么我应该为注释公开单独的API,对吗?首先,在编码之前,你应该坚持,好好考虑你的设计。:)你会有什么评论?为何你会在哪里使用它们?。。你首先必须对你想要达到的目标进行抽象设计,然后。。这取决于你认为你的评论是什么。在您当前的示例中,非常清楚,您有一个帖子,并且您有他们各自的评论。因此,由于PID没有person是不存在的,类似地,如果您没有它的父帖子(例如,如果您删除帖子),则注释也不存在。
@GetMapping("/api/posts/{id}/comments/{commendId}") //commentId is optional
@PostMapping("/api/posts/{id}/comments/") //you don't need any {commendId} here, just post the payload