Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Batching type resolution #1867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hrkfdn opened this issue Oct 11, 2023 · 4 comments
Closed

Batching type resolution #1867

hrkfdn opened this issue Oct 11, 2023 · 4 comments
Assignees

Comments

@hrkfdn
Copy link

hrkfdn commented Oct 11, 2023

With #1514 the interface for type resolvers has changed to pass a single representation instead of multiple representations. This was done to be more streamlined with other subgraph libraries which makes sense.

However, it comes with the disadvantage that type resolution can not be batched anymore. In our case, we would do a batch load from DynamoDB when receiving representations as that is more efficient than running a query per requested type. With the current interface this is not possible.

What would be the way to reproduce such a logic? I have asked on Slack and a data loader was suggested. From my understanding that does not mean the data loader will automatically be integrated with the type resolver, so I'm guessing some other gluing logic is needed.

Maybe some documentation or helpers in graphql-kotlin could be helpful to make the migration to v7 a little easier?

@samuelAndalon
Copy link
Contributor

samuelAndalon commented Oct 16, 2023

Hello, thank you for reaching out, as you well mentioned, we decided to refactor the federated type resolution to match with other federation implementations,

you can refer to the federation section of the documentation to check how to use DataLoaders, the only constrain is that you will have to use the FederatedTypePromiseResolver, FederatedTypeSuspendResolver is incompatible with DataLoader's technique as it relies on coroutines

here you can learn more about how to use DataLoaders in graphql-kotlin

@hrkfdn
Copy link
Author

hrkfdn commented Oct 18, 2023

Hey @samuelAndalon, thanks for the response.

I'm not sure I fully understood. How would I use FederatedTypePromiseResolver with batch loading with a single representation?

@samuelAndalon
Copy link
Contributor

I'm not sure I fully understood. How would I use FederatedTypePromiseResolver with batch loading with a single representation?

  1. Define your resolvers for federated entities
// This service does not own the "Product" type but is extending it with new fields
@KeyDirective(fields = FieldSet("id"))
@ExtendsDirective
class Product(@ExternalDirective val id: String) {
  fun newField(): String = getNewFieldByProductId(id)
}

// This is how the "Product" class is created from the "_entities" query using promise resolver
class ProductResolver : FederatedTypePromiseResolver<Product> {
    override val typeName: String = "Product"

    override fun resolve(
        environment: DataFetchingEnvironment,
        representation: Map<String, Any>
    ): CompletableFuture<Product?> {
        val id = representation["id"]?.toString()
        // use dataloader to resolve Product by id
        return environment.getDataLoader<String, Product?>("ProductDataLoader").load(id)
    }
}
  1. Define your DataLoader
@Service
class ProductDataLoader : KotlinDataLoader<ID, User> {
    override val dataLoaderName = "ProductDataLoader"
    override fun getDataLoader(graphQLContext: GraphQLContext) =
        DataLoaderFactory.newDataLoader<ID, User> { ids ->
            // call your DB here
        }
}

@samuelAndalon
Copy link
Contributor

please let me know if you need more help, i just copy-pasted what is in the documentation

@samuelAndalon samuelAndalon self-assigned this Oct 18, 2023
@ExpediaGroup ExpediaGroup locked and limited conversation to collaborators Oct 18, 2023
@samuelAndalon samuelAndalon converted this issue into discussion #1869 Oct 18, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Development

No branches or pull requests

2 participants