The problem background

Graphql has @skip and @include built in to determine whether to skip the parsing of a field, and the arguments are of type bool, but real business scenarios are often more complex. For example, we want users with userId less than 100 to see the coupon, or we can configure the query to determine which fields can be obtained by the version parameter.

The following query is expected to be available only to v2 clients. This logic should either be implemented in the DataFetcher corresponding to the email, or directly obtain and return the excess data. The first approach is not flexible enough, and the second approach is not acceptable when email acquisition costs are high, such as a network call.

query userInfoQuery($userId:Int){
    consumer{
        userInfo(userId: $userId){
            userId
            age
            name
            email
        }
    }
}
Copy the code

The solution

Graphql provides a directive mechanism, similar to Java annotations, that can be used to dynamically extend graphQL’s query execution capabilities.

The definition is an instruction to get a field:

directive @includeBy(predicate: String! , dependencySources:[String!] ) on FIELDCopy the code
  • Predicate: Determines whether the expression for the field is resolved. The expression takes query variables (along with other @fetchSource: advanced uses, described later).

@includeby is an extended version of graphQL’s built-in directive @Include, which determines whether to request the field by using an expression that takes query variables and other @fetchSources.

FetchSource for advanced use, refer to Grapqhl-Calculator README.

Use @includeby to query as follows. Only if the expression is true will the DataFetcher corresponding to the email be executed.

query queryMoreDetail_case01($userId:Int,$clientVersion:String){ consumer{ userInfo( userId: $userId, # Restricted by graphQL native syntax validation, variables must be explicitly used as parameters clientVersion: $clientVersion){userId age name # email @includeby (predicate: "clientVersion == 'v2'")}}} $clientVersion){userId age name #Copy the code

This capability is achieved through graphQL-Java-Calculator, a component based on an instruction system that provides data choreography, dynamic computation, and control flow capabilities for GraphQL queries. The implementation code is referred to @includeby exmaple, and the framework uses Example for a complete Example.

Contact the feedback

As an active contributor of GraphQL-Java component, the author mainly participated in the instruction capability upgrade and syntax verification and improvement of version 15 and 16, and successively engaged in the platform work of GraphQL in Meituan and Kuaishou. Welcome to use GraphQL-Java-Calculator, look forward to using feedback and participation in building, welcome interested students star attention.

Other articles:

  • Graphql computation instruction @filter: query in the implementation of collection filtering
  • Graphql calculation instruction @sortby: query to achieve the list of fields sort