github Netflix/dgs-framework v4.2.0

latest releases: v8.5.7-rc.1, v8.5.6, v8.5.6-rc.2...
2 years ago

What’s Changed

Support returning Mono/Flux from data fetchers (#389)

You can now return a Mono or Flux from a Data Fetcher. The framework will now transform a Mono or Flux object to a CompletableFuture automatically such that graphql-java can process its execution. Since graphql-java is already executing async this doesn't add any extra blocking.

New Metered Tags: gql.operation, gql.operation.name, gql.query.complexity, gql.query.sig.hash

The gql.resolver, gql.dataLoader, and gql.error timers will now express the following tags:

  • gql.operation: QUERY, MUTATION, SUBSCRIPTION are the possible values. These represent the GraphQL operation that is executed.

  • gql.operation.name: GraphQL operation name if any. There is only one operation name per execution. If the GraphQL query does not have an operation name, anonymous is used instead. Since the cardinality of the value is high it will be limited. More on how you can configure such limit below.

  • gql.query.sig.hash: Query Signature Hash of the query that was executed. Absent in case the query failed to pass GraphQL validation. Since the cardinality of the value is high it will be limited. More on how you can configure such limit below.

Note, in addition we are changing the name of the qgl.queryComplexity tag to gql.query.complexity to better express that the complexity is a part of the query and be inline with gql.query.sig.hash tag.

The Query Signature, is defined as the tuple of the GraphQL AST Signature of the GraphQL Document and the Query Signature Hash. The signature of a query is defined as follows:

A canonical AST which removes excess operations, removes any field aliases,
hides literal values and sorts the result into a canonical query
Ref graphql-java

The Query Signature Hash is the Hex 256 SHA string produced by encoding the Query Signature. While we can't tag a metric by the Query Signature due its length, we can use the Query Signature Hash as now expressed by the gql.query.sig.hash tag.

New Configuration Properties

  • management.metrics.dgs-graphql.query-signature.enabled: If true it will enable the calculation of GQL Query Signature. This will enable the tagging of gql metrics with the gql.query.sig.hash. A QuerySignatureRepositor component will also be available for container injection. It will be able to resolve a Document and InstrumentationExecutionParameters tuple to the QuerySignature. This can be useful if you want to leverage such object to add additional information to your Logs, Tracing Spans, etc.

  • management.metrics.dgs-graphql.query-signature.caching.enabled: By default the calculation of the signature will be cached. You can turn this off by setting this property to false. Note that this will not turn the calculation of the signature off, it will just disable the cache. If you want to turn it off use management.metrics.dgs-graphql.query-signature.enabled.

  • management.metrics.dgs-graphql.tags.limiter.limit: Defaults to100, sets the cardinality limit for the values of the gql.query.sig.hash and gql.operation.name tags. This limits the number of different values expressed in such tag, protecting the backing metric service form a cardinality explosion. The cardinality limit is per tag.

Improve error handling and null data semantics for entity fetchers. (#383)

DGS Entity Fetchers can now return null instead of creating an empty object that represents an entity. Previously, this would result in a DGSEntityNotFoundException with the following result, which was not compliant with federation spec:

{
  "errors": [
    {
      "message": "com.netflix.graphql.dgs.exceptions.MissingDgsEntityFetcherException: Missing @DgsEntityFetcher for type Movie",
      "locations": [],
      "path": [
        "_entities"
      ],
      "extensions": {
        "errorType": "INTERNAL"
      }
    }
  ],
data: null

The implementation is now returning the expected null entities array, for valid use cases where null data is expected :

{ 
  "data": {
    "_entities": [
      null
    ]
  }
}

We are also improving the handling of exceptions such that it allows us to return partial results. The exceptions errors are now populated for each entity as part of the error data in the result, along with an empty entities array as data. Previously, partial results were not being returned in case of exceptions. We can now get partial results along with the errors:

{
  "errors": [
    {
      "message": "java.lang.RuntimeException: Test entity exception",
      "locations": [],
      "path": [
        "_entities"
      ],
      "extensions": {
        "errorType": "INTERNAL"
      }
    }
  ],
  "data": {
    "_entities": [
      {
        "__typename": "Movie",
        "movieId": 1133,
        "fakeReviews": {
          "pageInfo": {
            "hasPreviousPage": false
          }
        }
      },
      null,
    ]
  }
}

Complete list of changes

Don't miss a new dgs-framework release

NewReleases is sending notifications on new releases.