diff --git a/lesson_26/api/java/api_app/src/main/java/com/codedifferently/lesson26/web/MediaItemsController.java b/lesson_26/api/java/api_app/src/main/java/com/codedifferently/lesson26/web/MediaItemsController.java index bbbc45e41..899e528e5 100644 --- a/lesson_26/api/java/api_app/src/main/java/com/codedifferently/lesson26/web/MediaItemsController.java +++ b/lesson_26/api/java/api_app/src/main/java/com/codedifferently/lesson26/web/MediaItemsController.java @@ -1,19 +1,34 @@ package com.codedifferently.lesson26.web; -import com.codedifferently.lesson26.library.Librarian; -import com.codedifferently.lesson26.library.Library; -import com.codedifferently.lesson26.library.MediaItem; -import com.codedifferently.lesson26.library.search.SearchCriteria; import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.UUID; + import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.codedifferently.lesson26.library.Librarian; +import com.codedifferently.lesson26.library.Library; +import com.codedifferently.lesson26.library.MediaItem; +import com.codedifferently.lesson26.library.search.SearchCriteria; + +import jakarta.validation.Valid; + @RestController @CrossOrigin +@RequestMapping("/api") public class MediaItemsController { private final Library library; @@ -31,4 +46,53 @@ public ResponseEntity getItems() { var response = GetMediaItemsResponse.builder().items(responseItems).build(); return ResponseEntity.ok(response); } + + @GetMapping("/items/{id}") + public ResponseEntity getItemById(@PathVariable String id) { + try { + Set items = library.search((SearchCriteria.builder().id(id).build())); + if (items.isEmpty()) { + return ResponseEntity.notFound().build(); + } + MediaItemResponse response = MediaItemResponse.from(items.iterator().next()); + return ResponseEntity.ok(response); + } catch (IllegalArgumentException e) { + return ResponseEntity.notFound().build(); + } + } + + @PostMapping("/items") + public ResponseEntity createItem(@Valid @RequestBody CreateMediaItemRequest request) { + try { + MediaItem item = MediaItemRequest.asMediaItem(request.getItem()); + library.addMediaItem(item, librarian); + var response = (CreateMediaItemResponse.builder()).item(MediaItemResponse.from(item)).build(); + return ResponseEntity.ok(response); + } catch (IllegalArgumentException e) { + return ResponseEntity.badRequest().build(); + } + } + + @DeleteMapping("/items/{id}") + public ResponseEntity deleteItemById(@PathVariable("id") String id) { + try { + UUID uuid = UUID.fromString(id); + Set items = library.search(SearchCriteria.builder().id(id).build()); + if (items.isEmpty()) { + return ResponseEntity.notFound().build(); + } + library.removeMediaItem(uuid, librarian); + return ResponseEntity.noContent().build(); + } catch (IllegalArgumentException e) { + return ResponseEntity.notFound().build(); + } + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity>> handleValidationErrors( + MethodArgumentNotValidException ex) { + List errors = + ex.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).toList(); + return ResponseEntity.badRequest().body(Map.of("errors", errors)); + } }