如何正确构建REST-API端点

时间:2019-07-28 03:45:27

标签: java spring rest spring-restcontroller

即时通讯(REST)API相当新。

我想要这样的东西

POST http://localhost/posts/ <--- PostsController.java
GET http://localhost/posts/{id} <--- PostsController.java
POST http://localhost/posts/{id}/comments <--- CommentsController.java
GET http://localhost/posts/{id}/comments <--- CommentsController.java
GET http://localhost/posts/{id}/comments/{id} <--- CommentsController.java

以下控制器处理/posts和另一个控制器处理程序/comments的地方

PostsController.java

@RestController
@RequestMapping("/posts")
public class PostsController {
   // something
}

CommentsController.java

@RestController
@RequestMapping("/comments")
public class CommentsController {
 //do something
}

我如何在拥有不同控制器的同时维护上述网址?

2 个答案:

答案 0 :(得分:7)

这是两个带有端点的控制器的框架,但是仍然可以将所有这些端点都放在一个控制器中或不同的控制器中,有人基于方法区分它们,有人基于路径来区分它们,所以我相信这完全是开发人员的经验如何设计

PostsController.java

@RestController
@RequestMapping("/posts")
public class PostsController {

@PostMapping("/")
public String createPosts() {

    return "createPosts";

}

@GetMapping("/{id}")
public String getPosts(@PathVariable(name = "id") String id) {
    return "getPosts......" + id;
   }

}

CommentsController.java

@RestController
@RequestMapping("/posts/{id}/comments")
public class CommentsController {

@PostMapping
public String createComment(@PathVariable(name = "id") String id) {
    return "createComment..." + id;
}

@GetMapping
public String getComment(@PathVariable(name = "id") String id) {
    return "getComment..." + id;
}

@GetMapping("/{id1@Path}")
public String getCommentById(@PathVariable(name = "id") String id, @PathVariable(name = "id1") String id1) {
    return "getComment..." + id + "...." + id1;
     }

 }

答案 1 :(得分:4)

我将在这里分享我的经验。 当我与Rest控制器一起工作时,我总是试图理解什么是“核心”实体-我们要处理的概念以及什么是查询标准。通常,“核心”实体会出现在上下文路径之后。

请注意,这实际上并不取决于数据库级别的实际实现。

因此,似乎所有情况实际上都与“ post”实体有关,这就是为什么您将其放在首位的原因(在通过邮寄发表评论的情况下,您没有选择类似{{1 }}没关系,这只意味着帖子是您服务的“主要”实体。

在这种情况下,我认为所有操作都可以在http://localhost/comments?post=123中完成。

现在是有关Spring / SpringBoot中控制器的重要说明。 人们倾向于将业务逻辑放入这些控制器中,我相信这是一个错误。控制器不应该包含任何实际逻辑,也许可以包含一些轻量级的输入转换/验证,仅此而已。将真正的工作留给“服务”而不是控制器,让控制器成为您后端的入口点。现在为什么要说这个?因为如果以这种方式编写的控制器实际上是很小的类,那么您将不会获得一个可以处理所有控制器的“巨型”类,我相信这可能是将其分离到不同控制器的一个论点。

好,那么在这种情况下,评论是什么?它取决于您的想法,但是正如您在端点列表中所写的那样,它是post的属性(属于该post /始终与该post相关联的东西),因此它是“搜索条件”:给我一条带有评论的帖子,只给我一个没有评论的帖子,给我一个仅包含今天和昨天的评论的帖子,关键是您总是查询“ post”,而不是评论。

从纯粹的技术角度来看,在弹簧启动时进入控制器类的PostsController表示该控制器只能查询@RequestMapping。 您还可以在/post批注中设置不同的值,但这是 它。如果应该足够灵活地设计休息控制器的级别。