I have 3 entities: Book
(parent), AntiqueBook
(extends Book), ScienceJournal
(extends Book).
The difference of AntiqueBook and ScienceJournal to Book is that each of them have an additional property than the parent (releaseYear
and scienceindex
, respectively).
Endpoint in the controller to create a new Book object:
@PostMapping("/books")
Book newBook(@RequestBody Book book) {
return service.save(book);
}
The method in service:
public Book save(Book book) {
return repository.save(book);
}
How can I create an AntiqueBook and ScienceJournal objects by only using this endpoint? For example, to check if @RequestBody has the property releaseYear (create AntiqueBook) or scienceIndex (create ScienceJournal). If it does not have either of these, then create Book.
For now, as a workaround, I created 2 additional endpoints to AntiqueBook and ScienceJournal, but I want to avoid this. I'm also having issues with the 'update' endpoint. If I can solve this one, then I can solve that one as well.
CodePudding user response:
You have to annotate your Book DTO with @JsonTypeInfo
and @JsonSubtypes
to let Jackson/Spring know how to unmarshal it.
Here's an example:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = AntiqueBook.class, name = "ANTIQUE"),
@JsonSubTypes.Type(value = ScienceBook.class, name = "SCIENCE")
})
public class Book {
private final String isbn;
public Book(String isbn) {
this.isbn = isbn;
}
public String getIsbn() {
return isbn;
}
}
public class AntiqueBook extends Book{
private final String year;
public AntiqueBook(String isbn, String year) {
super(isbn);
this.year = year;
}
public String getYear() {
return year;
}
}
public class ScienceBook extends Book{
private final String author;
public ScienceBook(String isbn, String author) {
super(isbn);
this.author = author;
}
public String getAuthor() {
return author;
}
}
@RestController
public class BookController {
@PostMapping("/books")
Book newBook(@RequestBody Book book) {
return book;
}
}
$>curl -X POST localhost:8080/books -d '{"isbn":"AAAA", "year":"2020", "type":"ANTIQUE"}' -H "Content-Type: application/json"
{"type":"ANTIQUE","isbn":"AAAA","year":"2020"}
$> curl -X POST localhost:8080/books -d '{"isbn":"AAAA", "author":"John", "type":"SCIENCE"}' -H "Content-Type: application/json"
{"type":"SCIENCE","isbn":"AAAA","author":"John"}