Skip to content

Commit e0a3134

Browse files
committed
Parse the request body
1 parent a69074c commit e0a3134

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

todo-api/src/main/java/lol/maki/dev/todo/TodoController.java

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package lol.maki.dev.todo;
22

3+
import am.ik.yavi.arguments.Arguments;
4+
import am.ik.yavi.arguments.Arguments1Validator;
5+
import am.ik.yavi.builder.StringValidatorBuilder;
36
import am.ik.yavi.core.ConstraintViolations;
47
import am.ik.yavi.core.ConstraintViolationsException;
58
import java.net.URI;
69
import java.util.List;
710
import java.util.Map;
11+
import java.util.Set;
812
import java.util.UUID;
913
import org.springframework.http.HttpStatus;
1014
import org.springframework.http.ResponseEntity;
@@ -44,20 +48,21 @@ public ResponseEntity<Todo> getTodo(@PathVariable("todoId") UUID todoId) {
4448
}
4549

4650
@PostMapping(path = "")
47-
public ResponseEntity<Todo> postTodos(@RequestBody Map<String, Object> request, @AuthenticationPrincipal Jwt jwt,
51+
public ResponseEntity<Todo> postTodos(@RequestBody Map<String, String> request, @AuthenticationPrincipal Jwt jwt,
4852
UriComponentsBuilder builder) {
53+
TodoCreateRequest req = TodoCreateRequest.parse(request);
4954
String email = jwt.getClaimAsString("email");
50-
Todo created = this.todoService.create((String) request.get("todoTitle"), email);
55+
Todo created = this.todoService.create(req.todoTitle(), email);
5156
URI uri = builder.pathSegment("todos", created.todoId().toString()).build().toUri();
5257
return ResponseEntity.created(uri).body(created);
5358
}
5459

5560
@PatchMapping(path = "/{todoId}")
56-
public ResponseEntity<Todo> patchTodo(@PathVariable("todoId") UUID todoId, @RequestBody Map<String, Object> request,
61+
public ResponseEntity<Todo> patchTodo(@PathVariable("todoId") UUID todoId, @RequestBody Map<String, String> request,
5762
@AuthenticationPrincipal Jwt jwt) {
63+
TodoUpdateRequest req = TodoUpdateRequest.parse(request);
5864
String email = jwt.getClaimAsString("email");
59-
Todo updated = this.todoService.update(todoId, (String) request.get("todoTitle"),
60-
(Boolean) request.get("finished"), email);
65+
Todo updated = this.todoService.update(todoId, req.todoTitle(), req.finished(), email);
6166
return ResponseEntity.ok(updated);
6267
}
6368

@@ -79,4 +84,27 @@ public ResponseEntity<?> handleConstraintViolations(ConstraintViolationsExceptio
7984
ConstraintViolations.of(e.violations()).details()));
8085
}
8186

87+
record TodoCreateRequest(String todoTitle) {
88+
private static final Arguments1Validator<Map<String, String>, TodoCreateRequest> validator = Todo.todoTitleValidator
89+
.andThen(TodoCreateRequest::new)
90+
.compose(map -> map.get("todoTitle"));
91+
92+
static TodoCreateRequest parse(Map<String, String> map) {
93+
return validator.validated(map);
94+
}
95+
}
96+
97+
record TodoUpdateRequest(String todoTitle, Boolean finished) {
98+
private static final Arguments1Validator<Map<String, String>, TodoUpdateRequest> validator = Todo.todoTitleValidator
99+
.split(StringValidatorBuilder.of("finished", c -> c.oneOf(Set.of("true", "false")))
100+
.build(Boolean::parseBoolean)
101+
.andThen(Todo.finishedValidator))
102+
.apply(TodoUpdateRequest::new)
103+
.compose(map -> Arguments.of(map.get("todoTitle"), map.get("finished")));
104+
105+
static TodoUpdateRequest parse(Map<String, String> map) {
106+
return validator.validated(map);
107+
}
108+
}
109+
82110
}

todo-api/src/test/java/lol/maki/dev/todo/TodoApiApplicationTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ void shouldReturnBadRequestForInvalidTodoUpdate() {
298298
.uri("/todos/{todoId}", "00000000-0000-0000-0000-000000000001")
299299
.contentType(MediaType.APPLICATION_JSON)
300300
.body("""
301-
{"finished": true, "todoTitle": "%s"}
301+
{"finished": "bar", "todoTitle": "%s"}
302302
""".formatted("a".repeat(256)))
303303
.headers(httpHeaders -> httpHeaders.setBearerAuth(accessToken))
304304
.retrieve()
@@ -307,9 +307,11 @@ void shouldReturnBadRequestForInvalidTodoUpdate() {
307307
assertThat(response.getBody()).isNotNull();
308308
assertThat(response.getBody().get("message")).isEqualTo(new TextNode("Validation failed"));
309309
assertThat(response.getBody().has("violations")).isTrue();
310-
assertThat(response.getBody().get("violations").size()).isEqualTo(1);
310+
assertThat(response.getBody().get("violations").size()).isEqualTo(2);
311311
assertThat(response.getBody().get("violations").get(0).get("defaultMessage")).isEqualTo(
312312
new TextNode("The size of \"todoTitle\" must be less than or equal to 255. The given size is 256"));
313+
assertThat(response.getBody().get("violations").get(1).get("defaultMessage"))
314+
.isEqualTo(new TextNode("\"finished\" must be one of the following values: [false, true]"));
313315
}
314316

315317
@Test

0 commit comments

Comments
 (0)