Operation System : Windows 10
IDE : IntelliJ
Requirements : Java 8 > , Postman ( For Testing)
Book | Tutorial : youtube tutorial
Java version : 12
Git Project : Here
Parts: Part 1
Goal
Learn how to indicate erroneous actions and objects in the REST Service
Solution
Main Changes
Model
During my research I encountered the use of validation annotations such as @NotNull, @NotEmpty etc, but I could not seem to get them to function as desired. However I will definitely look more into that in the nearer future and update this solution.
With that being said, in this solution the Todo bean/object was extended with a static method which confirms the validity of the provided arguments and returns a boolean value accordingly.
package com.example.demo.model;
import java.util.regex.Pattern;
import java.util.UUID;
public class Todo {
private final UUID id;
private String title;
…
public static boolean validateTodo(String title){
if(title == null) {
return false;
}
boolean isValid = true;
String pattern = "\\w+";
Pattern p = Pattern.compile(pattern);
return p.matcher(title).find();
}
}
Service
Since the Todo class has a validateTodo function, the TodoService will use this to check the correctness of the title value before a new Todo object is created. Hence both the addTodo and patchTodo methods are to be modified.
...
@Service
public class TodoService implements ITodoService {
private List<Todo> todos = new ArrayList<>();
@Override
public Todo addTodo(@JsonProperty("title") String title, @JsonProperty("isCompleted") boolean isCompleted) {
if(Todo.validateTodo(title) == false){
return null;
}
Todo todo = new Todo(UUID.randomUUID(), title, isCompleted);
todos.add(todo);
return todo;
}
@Override
public Todo patchTodo(UUID id, Todo patch) {
if(Todo.validateTodo(patch.getTitle()) == false){
return null;
}
Todo update = new Todo(id, patch.getTitle(), patch.getIsComplete());
List<Todo> newtodos = this.todos.stream().map(todo -> todo.getId().equals(id)? update : todo).collect(Collectors.toList());
this.todos = newtodos;
return patch;
}
...
These functions return either a valid Todo object or a null object depending on the validity of the given title.
Controller
One last modification is the <PATCH> and <POST> APIs. Since the TodoService returns either a valid Todo object or a Null object when creating a todo, the respective controllers should accommodate the changes and react accordingly. This means if the returned value is null, the controllers throw an exception indicating that something went wrong ( “title is invalid”) . Otherwise the todo object is returned along with a status 200.
....
@RestController
@RequestMapping("/api/v1/todos")
public class TodoController {
....
@PostMapping("/")
public ResponseEntity<Todo> addTodo(@RequestBody Todo todo){
Todo newtodo = this.todoService.addTodo(todo.getTitle(), todo.getIsComplete());
if(newtodo == null){
throw new TodoInvalidException();
}
return new ResponseEntity<Todo>(newtodo, HttpStatus.OK);
}
@PatchMapping("/{id}")
public ResponseEntity<Todo> patchTodo(@PathVariable("id") UUID id, @RequestBody Todo patch ){
Todo updateTodo = this.todoService.patchTodo(id,patch);
if(updateTodo == null){
throw new TodoInvalidException();
}
return new ResponseEntity<Todo>(updateTodo, HttpStatus.OK);
}
....
}
Author Notes
This is most likely not the cleanest implementation, just a heads up.
Links
- Validating Form Input
- Validation in Spring Boot
- Practice RegEXP
- Using Spring ResponseEntity to Manipulate the HTTP Response
- Interface BindingResult
- getAllErrors
- ObjectError
- Regular expressions in Java – Tutorial
- RuntimeException
- Exception Handling in Spring MVC
- How to use Regex in Java to pattern match?