Reputation: 361
If you were designing an library application lets a citizen borrow & return books how would you design it from the database perspective.
I did this i created a Book Class
@Entity
public class Book {
private Integer id;
private String title;
private Integer numberOfCopies;
and when a user makes a request to citizen/borrow/{id} (With Book id The numberOfCopies variable adds one up or down
@GetMapping(path = "citizen/borrow/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public Book borrowBook(@PathVariable Integer id) {
Book book = bookRepo.findById(id).orElseThrow(() -> new BookNotFoundException(id));
Integer numberOfCopies = book.getNumberOfCopies();
if (numberOfCopies == 0) throw new BookNotAvailableException();
book.setNumberOfCopies(numberOfCopies - 1);
bookRepo.save(book);
return book;
}
how would you realize such an application? Is this good programming style or what you think?
Upvotes: 1
Views: 1332
Reputation: 2571
First, according to REST practices, your endpoint (or resource) should be self-descriptive.
This path citizen/borrow/{id}
looks like you are borrowing citizens, not books. It would make more sense to make resource like this: /v1/book/{id}/borrow
as a POST request because modifying query will be executed.
Second, move your reusable logic into
@Service
layer.
I have a rule to never inject the repository into controllers. All saves and updates should be handled in the service layer and return a DTO (Data Transfer Object).
Third, handle your input in your controller layer.
Your @PathVariable
may be null. This can cause problems deeper in the code. Why not just handle it right away and throw an exception from the beginning?
if (id == null)
throw new new BookNotFoundException();
Upvotes: 1