Changed API root endpoint

This commit is contained in:
Marco Cetica 2024-01-17 09:43:32 +01:00
parent 0dc8d42727
commit 050d3588b7
Signed by: marco
GPG Key ID: 45060A949E90D0FD
5 changed files with 28 additions and 31 deletions

View File

@ -72,7 +72,7 @@ By default, the following parameters are used:
Be sure to update these values by editing the`docker-compose.yml` file. Once the containers Be sure to update these values by editing the`docker-compose.yml` file. Once the containers
are deployed, you can expose the application through a reverse proxy: are deployed, you can expose the application through a reverse proxy:
```nginx ```nginx
location / { location /api {
proxy_pass http://127.0.0.1:3000; proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -84,36 +84,36 @@ location / {
## Endpoints ## Endpoints
The backend exposes the following REST APIs: The backend exposes the following REST APIs:
### `POST` New User(`/users/new`): ### `POST` New User(`/api/users/new`):
_Description_: Add new user. _Description_: Add new user.
_Parameters_: **username**(`string`), **email**(`string`) **password**(`string`). _Parameters_: **username**(`string`), **email**(`string`) **password**(`string`).
### `DELETE` Delete User(`/users/delete`): ### `DELETE` Delete User(`/api/users/delete`):
_Description_: Delete an existing user. _Description_: Delete an existing user.
_Parameters_: **email**(`string`) **password**(`string`). _Parameters_: **email**(`string`) **password**(`string`).
### `GET` Post List(`/posts`): ### `GET` Post List(`/api/posts`):
_Description_: Retrieve all users. _Description_: Retrieve all users.
_Parameters_: none. _Parameters_: none.
### `GET` Post By ID(`/posts/{postID}`): ### `GET` Post By ID(`/api/posts/{postID}`):
_Description_: Search a post by its ID. _Description_: Search a post by its ID.
_Parameters_: none. _Parameters_: none.
### `GET` Post By Title(`/posts/bytitle`): ### `GET` Post By Title(`/api/posts/bytitle`):
_Description_: Search a post by its title. _Description_: Search a post by its title.
_Parameters_: **title**(`string`). _Parameters_: **title**(`string`).
### `POST` New Post(`/posts/new`): ### `POST` New Post(`/api/posts/new`):
_Description_: Add a new post. _Description_: Add a new post.
_Parameters_: **title**(`string`), **content**(`string`), **expirationDate**(`YYYY-MM-DD`), _Parameters_: **title**(`string`), **content**(`string`), **expirationDate**(`YYYY-MM-DD`),
**user**(`User`). **user**(`User`).
### `PUT` Edit Post(`/posts/{postID}`): ### `PUT` Edit Post(`/api/posts/{postID}`):
_Description_: Update an existing, non-anonymous post. _Description_: Update an existing, non-anonymous post.
_Parameters_: **title**(`string`), **content**(`string`), **user**(`User`). _Parameters_: **title**(`string`), **content**(`string`), **user**(`User`).
### `DELETE` Delete Post(`/posts/{postID}`): ### `DELETE` Delete Post(`/api/posts/{postID}`):
_Description_: Delete an existing, non-anonymous post. _Description_: Delete an existing, non-anonymous post.
_Parameters_: **user**(`User`). _Parameters_: **user**(`User`).
@ -123,7 +123,7 @@ Below there are some practical examples on how to use the REST API:
1. **Add a non-anonymous, perpetual post**(_note: the user must exist_) 1. **Add a non-anonymous, perpetual post**(_note: the user must exist_)
`POST` request to `/posts/new` with the following body: `POST` request to `/api/posts/new` with the following body:
```json ```json
{ {
"title": "Hello World", "title": "Hello World",
@ -138,7 +138,7 @@ Below there are some practical examples on how to use the REST API:
2. **Add an anonymous post with expiration date set to January 25, 2024** 2. **Add an anonymous post with expiration date set to January 25, 2024**
`POST` request to `/posts/new` with the following body: `POST` request to `/api/posts/new` with the following body:
```json ```json
{ {
"title": "Hello World", "title": "Hello World",
@ -149,7 +149,7 @@ Below there are some practical examples on how to use the REST API:
3. **Delete post "`afj45c`"** 3. **Delete post "`afj45c`"**
`DELETE` request to `/posts/afj45c` with the following body: `DELETE` request to `/api/posts/afj45c` with the following body:
```json ```json
{ {
"email": "john@example.com", "email": "john@example.com",

View File

@ -23,7 +23,7 @@ public class PostController {
* *
* @return the list of the posts * @return the list of the posts
*/ */
@GetMapping("/posts") @GetMapping("/api/posts")
public ResponseEntity<List<Post>> getPosts() { public ResponseEntity<List<Post>> getPosts() {
return new ResponseEntity<>(postService.getPosts(), HttpStatus.OK); return new ResponseEntity<>(postService.getPosts(), HttpStatus.OK);
} }
@ -34,7 +34,7 @@ public class PostController {
* @param postId the ID of the requested post * @param postId the ID of the requested post
* @return the content of the post * @return the content of the post
*/ */
@GetMapping("/posts/{postId}") @GetMapping("/api/posts/{postId}")
public ResponseEntity<String> getPostById(@PathVariable("postId") String postId) { public ResponseEntity<String> getPostById(@PathVariable("postId") String postId) {
var res = postService.getPostById(postId) var res = postService.getPostById(postId)
.map(post -> new JsonEmitter<>(post).emitJsonKey()) .map(post -> new JsonEmitter<>(post).emitJsonKey())
@ -54,7 +54,7 @@ public class PostController {
* Without the title, it acts the same as 'GET /posts' * Without the title, it acts the same as 'GET /posts'
* @return the list of posts * @return the list of posts
*/ */
@GetMapping("/posts/bytitle") @GetMapping("/api/posts/bytitle")
public ResponseEntity<List<Post>> getPostByTitle(@RequestBody Post req) { public ResponseEntity<List<Post>> getPostByTitle(@RequestBody Post req) {
return new ResponseEntity<>(postService.getPostByTitle(req.getTitle()), HttpStatus.OK); return new ResponseEntity<>(postService.getPostByTitle(req.getTitle()), HttpStatus.OK);
} }
@ -65,7 +65,7 @@ public class PostController {
* @param post the new post to be submitted * @param post the new post to be submitted
* @return on success the new postId, on failure the error message * @return on success the new postId, on failure the error message
*/ */
@PostMapping("/posts/new") @PostMapping("/api/posts/new")
public ResponseEntity<String> submitPost(@Valid @RequestBody Post post) { public ResponseEntity<String> submitPost(@Valid @RequestBody Post post) {
var res = postService.addNewPost(post) var res = postService.addNewPost(post)
.map(postId -> new JsonEmitter<>(postId).emitJsonKey("post_id")) .map(postId -> new JsonEmitter<>(postId).emitJsonKey("post_id"))
@ -85,7 +85,7 @@ public class PostController {
* @param postId the id of the post to update * @param postId the id of the post to update
* @return on failure, the error message. * @return on failure, the error message.
*/ */
@PutMapping("/posts/{postId}") @PutMapping("/api/posts/{postId}")
public ResponseEntity<String> updatePost(@Valid @RequestBody Post post, @PathVariable("postId") String postId) { public ResponseEntity<String> updatePost(@Valid @RequestBody Post post, @PathVariable("postId") String postId) {
var res = postService.updatePost(post, postId); var res = postService.updatePost(post, postId);
@ -105,7 +105,7 @@ public class PostController {
* @param postId the post ID to delete * @param postId the post ID to delete
* @return on failure, the error message * @return on failure, the error message
*/ */
@DeleteMapping("/posts/{postId}") @DeleteMapping("/api/posts/{postId}")
public ResponseEntity<String> deletePost(@RequestBody User user, @PathVariable("postId") String postId) { public ResponseEntity<String> deletePost(@RequestBody User user, @PathVariable("postId") String postId) {
// Check if email and password are specified // Check if email and password are specified
if(user.getPassword() == null || user.getEmail() == null) { if(user.getPassword() == null || user.getEmail() == null) {

View File

@ -5,11 +5,8 @@ import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
@RestController @RestController
public class UserController { public class UserController {
@ -26,7 +23,7 @@ public class UserController {
* @param user the new user * @param user the new user
* @return on success, the userId, on failure the error message * @return on success, the userId, on failure the error message
*/ */
@PostMapping("/users/new") @PostMapping("/api/users/new")
public ResponseEntity<String> submitUser(@Valid @RequestBody User user) { public ResponseEntity<String> submitUser(@Valid @RequestBody User user) {
var res = userService.addNewUser(user) var res = userService.addNewUser(user)
.map(userId -> new JsonEmitter<>(userId).emitJsonKey("user_id")) .map(userId -> new JsonEmitter<>(userId).emitJsonKey("user_id"))
@ -45,7 +42,7 @@ public class UserController {
* @param user the email and the password of the user * @param user the email and the password of the user
* @return on failure, the error message * @return on failure, the error message
*/ */
@DeleteMapping("/users/delete") @DeleteMapping("/api/users/delete")
public ResponseEntity<String> deleteUser(@RequestBody User user) { public ResponseEntity<String> deleteUser(@RequestBody User user) {
// Check if email and password are specified // Check if email and password are specified
if(user.getPassword() == null || user.getEmail() == null) { if(user.getPassword() == null || user.getEmail() == null) {

View File

@ -44,7 +44,7 @@ public class PostControllerTests {
when(postService.getPosts()).thenReturn(List.of(post)); when(postService.getPosts()).thenReturn(List.of(post));
mockMvc.perform(MockMvcRequestBuilders.get("/posts") mockMvc.perform(MockMvcRequestBuilders.get("/api/posts")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(post))) .content(objectMapper.writeValueAsString(post)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -62,7 +62,7 @@ public class PostControllerTests {
when(postService.getPostById(anyString())).thenReturn(Either.right(any(Post.class))); when(postService.getPostById(anyString())).thenReturn(Either.right(any(Post.class)));
mockMvc.perform(MockMvcRequestBuilders.get("/posts/abc123") mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/abc123")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(post))) .content(objectMapper.writeValueAsString(post)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -80,7 +80,7 @@ public class PostControllerTests {
when(postService.getPostByTitle(anyString())).thenReturn(List.of(post)); when(postService.getPostByTitle(anyString())).thenReturn(List.of(post));
mockMvc.perform(MockMvcRequestBuilders.get("/posts/bytitle") mockMvc.perform(MockMvcRequestBuilders.get("/api/posts/bytitle")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(post))) .content(objectMapper.writeValueAsString(post)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -96,7 +96,7 @@ public class PostControllerTests {
when(postService.addNewPost(any(Post.class))).thenReturn(Either.right(anyString())); when(postService.addNewPost(any(Post.class))).thenReturn(Either.right(anyString()));
mockMvc.perform(MockMvcRequestBuilders.post("/posts/new") mockMvc.perform(MockMvcRequestBuilders.post("/api/posts/new")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(post))) .content(objectMapper.writeValueAsString(post)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -112,7 +112,7 @@ public class PostControllerTests {
when(postService.updatePost(any(Post.class), anyString())).thenReturn(Optional.empty()); when(postService.updatePost(any(Post.class), anyString())).thenReturn(Optional.empty());
mockMvc.perform(MockMvcRequestBuilders.put("/posts/abc123") mockMvc.perform(MockMvcRequestBuilders.put("/api/posts/abc123")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(post))) .content(objectMapper.writeValueAsString(post)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -128,7 +128,7 @@ public class PostControllerTests {
when(postService.deletePost(any(User.class), anyString())).thenReturn(Optional.empty()); when(postService.deletePost(any(User.class), anyString())).thenReturn(Optional.empty());
mockMvc.perform(MockMvcRequestBuilders.delete("/posts/abc123") mockMvc.perform(MockMvcRequestBuilders.delete("/api/posts/abc123")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user))) .content(objectMapper.writeValueAsString(user)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());

View File

@ -40,7 +40,7 @@ class UserControllerTest {
when(userService.addNewUser(any(User.class))).thenReturn(Either.right(anyString())); when(userService.addNewUser(any(User.class))).thenReturn(Either.right(anyString()));
mockMvc.perform(MockMvcRequestBuilders.post("/users/new") mockMvc.perform(MockMvcRequestBuilders.post("/api/users/new")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user))) .content(objectMapper.writeValueAsString(user)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());
@ -56,7 +56,7 @@ class UserControllerTest {
when(userService.deleteUser(any(User.class))).thenReturn(Optional.empty()); when(userService.deleteUser(any(User.class))).thenReturn(Optional.empty());
mockMvc.perform(MockMvcRequestBuilders.delete("/users/delete") mockMvc.perform(MockMvcRequestBuilders.delete("/api/users/delete")
.contentType(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(user))) .content(objectMapper.writeValueAsString(user)))
.andExpect(MockMvcResultMatchers.status().isOk()); .andExpect(MockMvcResultMatchers.status().isOk());