github Netflix/dgs-framework v4.5.0

latest releases: v9.1.2, v9.1.1, v9.1.0...
3 years ago

What’s Changed

⚠️ Client Codegen migration to graphql-dgs-codegen-client-core (#439) @berngp

As part of an effort to migrate the DGS Client Components that should belong to the DGS Codegen project, we are removing from the graphql-dgs-client module all components in the com.netflix.graphql.dgs.client.codegen package. If you depend on them you will have to use the DGS Codegen plugin, such plugin will add a new module automatically with the artifacts. This change will allow us to evolve the both projects independently. In other words, we will not need to release a new version of the DGS Framework if we need changes to the DGS Codegen components.

Implemented @connection directive for generating SDL types for cursor-based pagination. (#487) @srinivasankavitha

As a new feature we are releasing the new graphql-dgs-pagination module. It adds support for generating schema types for cursor-based pagination based on the relay spec.

The benefit is to avoid having the user define related Connection and Edge types in the schema for every type that needs to be paginated. The following example below shows the schema the user needs to define:

type Query {
      something: MovieConnection
}
            
type Movie @connection {
    movieID: ID
    title: String
}

Note the @connection directive against the type Movie. This will generate a MovieConnection and MovieEdge as follows:

type MovieConnection {
    edges: [MovieEdge]
    pageInfo: PageInfo
}

type MovieEdge {
    node: Movie
    cursor: String
}

type PageInfo {
    hasPreviousPage: Boolean!
    hasNextPage: Boolean!
    startCursor: String
    endCursor: String
}

PageInfo is generated only once, if necessary.

Add basic support for coroutines in datafetchers (#472) @paulbakker

You can now use Kotlin Coroutines to define datafetchers. For example, let's say we have a field called range that will compute the sum between two numbers. You could define your datafetcher as follows:

@DgsQuery
suspend fun range(@InputArgument from: Int, to: Int): Int = coroutineScope {
   var sum = 0
   withContext(executor.asCoroutineDispatcher()) {
           repeat(from.rangeTo(to).count()) {
                 sum++
                 // Forcing a blocking call to demonstrate running with a thread pool
                 Thread.sleep(50)
            }
     
         sum
   }
}

Using a coroutine is very similar to returning CompletableFuture. In fact, coroutines are internally resolved as CompletableFuture.
A coroutine (similar to returning CompletableFuture) marks a datafetcher as potentially async.
However, coroutine datafetchers are dispatched using the unconfined dispatcher, which in practice means they won't automatically get any parallel behavior. This means, that multiple datafetchers defined as coroutines will still not run in parallel.

To get parallel execution, the developer is in charge of setting up the correct context. A great way to do this is using an Executor.
Also remember that any thread-bound context, such as request data stored on thread-local, will not be available when executing on a different thread. An executor has to be set up explicitly for this.
Again, this is exactly the same when using CompletableFuture for parallel datafetcheres.

Complete list of changes

Don't miss a new dgs-framework release

NewReleases is sending notifications on new releases.