Closed2

kotlin 備忘録 〜GraphQL Kotlin編〜

norishionorishio

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)
    }
norishionorishio

type で別ドメインを組み合わせて、1queryで処理ができるように構造化する
 (WIP)

このスクラップは3ヶ月前にクローズされました