The problem background

When using GraphQL for query, many scenarios need to filter the list type fields, such as filtering the goods removed, users under the age of 18, coupons with 0 allowance, etc.

The following query, if you want to filter items that are not for sale (onSale==false), needs to be hardcoded.

query itemListByIds($ItemIds:[Int]){
    commodity{
        itemList(itemIds: $ItemIds){
            itemId
            onSale
            name
            salePrice
        }
    }
}
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.

Predicate: filter judgment expressions. Elements that result in true are retained.

directive @filter(predicate: String!) on FIELD
Copy the code

After the modification, the query is as follows:

query filterUnSaleCommodity($ItemIds:[Int]){ commodity{ filteredItemList: itemList(itemIds: $ItemIds) @filter(predicate: "onSale") {itemId onSale name salePrice}}}Copy the code

The specific implementation

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.

Config wrapperConfig = DefaultConfig.newConfig().build();

DefaultGraphQLSourceBuilder graphqlSourceBuilder = new DefaultGraphQLSourceBuilder();
GraphQLSource graphqlSource = graphqlSourceBuilder
        .wrapperConfig(wrapperConfig)
        .originalSchema(
            // The original Schema object
            GraphQLSourceHolder.getDefaultSchema()
        ).build();

String query = "" +
        "query filterUnSaleCommodity($itemIds:[Int]){\n" +
        " commodity{\n" +
        " itemList(itemIds: $itemIds)\n" +
        " @filter(predicate: "onSale")\n" +
        " {\n" +
        " itemId\n" +
        " onSale\n" +
        " name\n" +
        " salePrice\n" +
        " }\n" +
        " \n" +
        " }\n" +
        "}";
ExecutionInput input = ExecutionInput
        .newExecutionInput(query)
        .variables(Collections.singletonMap("itemIds", Arrays.asList(1.2.3)))
        .build();

ExecutionResult result = graphqlSource.getGraphQL().execute(input);
Copy the code

See Example for a complete Example.

Contact the feedback

Welcome to try graphQL-Java-Calculator. The author has been engaged in the platform work of GraphQL in Meituan and Kuaishou successively. As an active contributor of GraphQL-Java component, I look forward to using it and suggestions.