Projekcje z dokumentów MongoDB i Kotlinowy data class

0

Zastanawiam się czy da się jakoś połączyć projekcje MongoDB z data class Kotlina, któego pola są non-nullable.
Przykład - mam API GraphQLowe, z taką schemą

type Query {
    books: [Book]
}

type Book {
    id: ID!
    title: String!
    author: String!
    pagesCount: Int!
}

No i mój kod sprowadza się do czegoś takiego

@Document(collection = "book")
data class Book(@Id val id: String? = null,
				val title: String,
				val author: String,
				val pagesCount: Int)

@Repository
class BookRepository(private val mongoTemplate: MongoTemplate) {
	fun findAll(): List<Book> = mongoTemplate.findAll(Book::class.java)
}

@Component
class BookResolver(private val bookRepository: BookRepository): GraphQLQueryResolver {
	fun books() = bookRepository.findAll()
}

I działa, mogę skonstruować query GraphQL tak by wyciągnąć np. tylko title i pagesCount i klient korzystający z API dostanie tylko te dwa pola. Po stronie bazy danych, jednak nadal wyciągać będę cały obiekt Book, również pola które mnie nie interesują, które potencjalnie mogą być jakimiś dużymi obiektami.

Alternatywa to zrobienie czegoś takiego

@Document(collection = "book")
data class BookProjection(val title: String, val pagesCount: Int)

Jednak oznacza to, że potrzebowałbym takie projekcje dla każdej możliwej kombinacji pól w Book.
No ale mongoTemplate udostępnia opcje, by wskazać które pola chcę wyciągnąć, mógłym więc wymagane parametry przechwycić z query GraphQL i uzyć tutaj.

	fun findBooksProjection(): List<Book> {
		val query = Query()
		query.fields().include("title", "pagesCount")
		return mongoTemplate.find(query, Book::class.java)
	}

Tyle, że to oczywiście nie zadziała, bo mój data class ma wszystkie pola non-nullable

Failed to instantiate com.example.demo.Book using constructor fun <init>(kotlin.String?, kotlin.String, kotlin.String, kotlin.Int):

No więc pytanie, czy jest na to jakiś sposób inny niż oznaczenie wszytkich pól w takim dokumencie jako nullable? Teoretycznie mógłbym system podzielić wg. CQRS i w przypadku query wyciągać coś w rodzaju wspomnianego BookProjection, jednak ze wszystkimi polami nullable, wtedy nie ma już tyle logiki i potencjalnych nulli obsługi co w przypadku command, gdzie nadal mógłym działać na pierwotnej encji. Chciałbym się jednak upewnić czy nie ma innej drogi, może Kotlin zaskoczy mnie czymś jeszcze.

0

To jest generalnie chyba dosyc problematyczne w statycznie typowanych jezykach. Ale moze Map<String, Any> jakos pomoze? Powinno sie dac jakos to serializowac do jsona.

EDIT: Gdzies chyba widzialem tez cos ala jsonObject (kotlinx.serialization?)

1

GraphQL-em się nie bawiłem, ale na świecie są pewne fundamenty i rzeczy, których nie da się przeskoczyć.

  1. Zwracasz encje z API, było o tym na forum z 1547 razy.
  2. Musisz zwrócić albo mapę albo obiekt klasy ze wszystkimi nullowalnymi polami, no nie da się inaczej :) masakra po stronie serwera, może da się jakoś lepiej zamodelować te zasoby

1 użytkowników online, w tym zalogowanych: 0, gości: 1