im quite new with REST-API.
i want to have something like this
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
Where the following controllers handle /posts
and another controller handler /comments
PostsController.java
@RestController
@RequestMapping("/posts")
public class PostsController {
// something
}
CommentsController.java
@RestController
@RequestMapping("/comments")
public class CommentsController {
//do something
}
How do i maintain the above url whilst having different controllers to handle it?
An Endpoint URL. An application implementing a RESTful API will define one or more URL endpoints with a domain, port, path, and/or querystring — for example, https://mydomain/user/123?format=json .
In general, URIs should be named with nouns that specify the contents of the resource, rather than adding a verb for the function that is being performed. For example, you should use https://api.example.com/users instead of https://api.example.com/getUsers.
The usual format used while sending resources is JSON REST API or XML.
Here is the skeleton for both the controllers with endpoints, But still you can also have all these endpoints in one controller or different, some people differentiate them based on methods, some based on paths, so i believe this is completely developer experience how to design this
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;
}
}
I'll share my expreience here. When I work with Rest controllers, I always try to understand what is the "core" entity - a notion we deal with and what are just criterias for queries. Usually the "core" entity appears right after the context path.
Note that this doesn't really depend on an actual implementation at the level of database.
So it looks like all the cases are actually about the "post" entity that's why you've put it in the first place (in the case of comments by post, you didn't opt for something like this http://localhost/comments?post=123
and that's ok, it just means that post is your "main" entity to serve.
In this case I think all the operations can be done in PostsController
.
Now an important side-note about controllers in Spring / SpringBoot. People tend to put business logic in these controllers and I believe its a mistake. Controllers should not contain any real logic, maybe some light input transformations / validations but that's it. Leave a real work to "Services" not to controllers, keep controllers to be an entry point for your backend. Now why I'm stating this? Because controllers, if written in this way are really small classes, so you won't get a one "giant" class that handles all, which, I believe, might be an argument for separation to different controllers.
Ok, so what is comments in this case? It depends on how you think about it, but as you wrote in end-points list, is a property of post (something that belongs to the post/ always associated with the post), so its a "Criteria of search": give me a post with comments, give me only a post without comments, give me a post that has comments only from today and yesterday, the point is that you always query for "post", not for comments.
From the purely technical standpoint, the @RequestMapping
in spring boot when put on controller class says that only /post
can be queried by this controller.
You can also set different values on @GetMapping/@PostMapping
annotations but that's
it. If should be flexible enough to design the level of rest controllers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With