Closed2
kotlin 備忘録 〜GraphQL Kotlin編〜
dataloaderについて
data loaderの実装をイメージを忘れないために、記録を書く.
今回は、仮にUserとUserが所属するCompanyの情報を返す想定で書いていく.
schemaイメージ
graphql
query {
users {
id
name
company {
id
name
}
}
}
ユーザー
data class User(
val id: Long,
val name: String,
@GraphQLIgnore
val companyId: Long
)
companyId はGraphQLには出さないけど、内部的にDataLoaderで使う
@GraphQLIgnore はgraphql-kotlinの環境で利用
会社
data class Company(
val id: Long,
val name: String
)
Companydataloaderの実装
Companyをuserと1:1で返す.
class CompanyDataLoader(
private val companyRepository: CompanyRepository
) : KotlinDataLoader<Long, CompanyType> {
override val dataLoaderName = "CompanyDataLoader"
override fun getDataLoader(graphQLContext: GraphQLContext): List<CompanyType> {
return DataLoaderFactory.newDataLoader(
BatchLoaderWithContext<Long, CompanyType> { companyIds, env ->
val context = env.getContext<GraphQLContext>()
CompletableFuture.supplyAsync {
val companies: List<CompanyEntity> = companyRepository.findbyIds(companyIds)
// Entity → Type に変換
val companyMap: Map<Long, CompanyType> = companies.associateBy(
{ it.id },
{ CompanyType(id = it.id, name = it.name) }
)
// 順序を合わせたListにして返す
companyIds.map { companyMap[it] }
}
},
DataLoaderOptions.newOptions()
.setCachingEnabled(true)
.setBatchLoaderContextProvider { graphQLContext }
)
}
}
細かい部分は、カスタマイズ可能.
User queryで追加
fun company(user: User, env: DataFetchingEnvironment): CompletableFuture<Company?> {
val dataLoader: DataLoader<Long, Company> = env.getDataLoader("COMPANY_LOADER")
return dataLoader.load(user.companyId)
}
type で別ドメインを組み合わせて、1queryで処理ができるように構造化する
(WIP)
このスクラップは3ヶ月前にクローズされました