Java USES Graphql to build query service details

  • 2020-05-19 04:57:41
  • OfStack

background

As React open source, facebook successively open source a lot of related projects, these projects within them have been used for many years, which attracted my attention is that this discussion is graphql, currently the only official nodejs version, because many company background technology stack is Java, so have graphql java edition, can be found in the github, nonsense not say, see the code directly, or go to the reader in detail, Internet cafes or digress.

GraphQLSchema

Schema is equivalent to a database, which is composed of many GraphQLFieldDefinition, and Field is equivalent to a database table/view. Each table/view is composed of name, query parameters, data structure and data.

1) define 1 data structure (GraphQLOutputType) field first, and then define 1 initialization method


private GraphQLOutputType userType;

private void initOutputType() {
   /**
    *  Member object structure 
    */
   userType = newObject()
       .name("User")
       .field(newFieldDefinition().name("id").type(GraphQLInt).build())
       .field(newFieldDefinition().name("age").type(GraphQLInt).build())
       .field(newFieldDefinition().name("sex").type(GraphQLInt).build())
       .field(newFieldDefinition().name("name").type(GraphQLString).build())
       .field(newFieldDefinition().name("pic").type(GraphQLString).build())
       .build();
}

2) define two more tables/views, including name, query parameters, data structure, and data retriever


 /**
   *  Query individual user information 
   * @return
   */
  private GraphQLFieldDefinition createUserField() {
    return GraphQLFieldDefinition.newFieldDefinition()
        .name("user")
        .argument(newArgument().name("id").type(GraphQLInt).build())
        .type(userType)
        .dataFetcher(environment -> {
          //  Get query parameters 
          int id = environment.getArgument("id");

          //  Execute the query ,  You can use it here 1 Some test data to illustrate the problem 
          User user = new User();
          user.setId(id);
          user.setAge(id + 15);
          user.setSex(id % 2);
          user.setName("Name_" + id);
          user.setPic("pic_" + id + ".jpg");
          return user;
        })
        .build();
  }

  /**
   *  Query multiple member information 
   * @return
   */
  private GraphQLFieldDefinition createUsersField() {
    return GraphQLFieldDefinition.newFieldDefinition()
        .name("users")
        .argument(newArgument().name("page").type(GraphQLInt).build())
        .argument(newArgument().name("size").type(GraphQLInt).build())
        .argument(newArgument().name("name").type(GraphQLString).build())
        .type(new GraphQLList(userType))
        .dataFetcher(environment -> {
          //  Get query parameters 
          int page = environment.getArgument("page");
          int size = environment.getArgument("size");
          String name = environment.getArgument("name");

          //  Execute the query ,  You can use it here 1 Some test data to illustrate the problem 
          List<User> list = new ArrayList<>(size);
          for (int i = 0; i < size; i++) {
            User user = new User();
            user.setId(i);
            user.setAge(i + 15);
            user.setSex(i % 2);
            user.setName(name + "_" + page + "_" + i);
            user.setPic("pic_" + i + ".jpg");
            list.add(user);
          }
          return list;
        })
        .build();
  }

3) then define and initialize an Schema containing 1 name and 1 or more tables/views (Field)


 private GraphQLSchema schema;

  public GraphSchema() {
    initOutputType();
    schema = GraphQLSchema.newSchema().query(newObject()
        .name("GraphQuery")
        .field(createUsersField())
        .field(createUserField())
        .build()).build();
  }

4) after completing the above steps, one model needs to be defined. The class name is not limited, but the structure needs to satisfy the previously defined data structure and must be public


public class User {
  private int id;
  private int age;
  private int sex;
  private String name;
  private String pic;
  // getter, setter...
}  

5) then write an main method to test 1


public static void main(String[] args) {
    GraphQLSchema schema = new GraphSchema().getSchema();

    String query1 = "{users(page:2,size:5,name:\"john\") {id,sex,name,pic}}";
    String query2 = "{user(id:6) {id,sex,name,pic}}";
    String query3 = "{user(id:6) {id,sex,name,pic},users(page:2,size:5,name:\"john\") {id,sex,name,pic}}";

    Map<String, Object> result1 = (Map<String, Object>) new GraphQL(schema).execute(query1).getData();
    Map<String, Object> result2 = (Map<String, Object>) new GraphQL(schema).execute(query2).getData();
    Map<String, Object> result3 = (Map<String, Object>) new GraphQL(schema).execute(query3).getData();

    //  Query user list 
    System.out.println(result1);
    //  Querying a single user 
    System.out.println(result2);
    //  Single user, follow user list 1 Check up 
    System.out.println(result3);

}

Output:


{users=[{id=0, sex=0, name=john_2_0, pic=pic_0.jpg}, {id=1, sex=1, name=john_2_1, pic=pic_1.jpg}, {id=2, sex=0, name=john_2_2, pic=pic_2.jpg}, {id=3, sex=1, name=john_2_3, pic=pic_3.jpg}, {id=4, sex=0, name=john_2_4, pic=pic_4.jpg}]}
{user={id=6, sex=0, name=Name_6, pic=pic_6.jpg}}
{user={id=6, sex=0, name=Name_6, pic=pic_6.jpg}, users=[{id=0, sex=0, name=john_2_0, pic=pic_0.jpg}, {id=1, sex=1, name=john_2_1, pic=pic_1.jpg}, {id=2, sex=0, name=john_2_2, pic=pic_2.jpg}, {id=3, sex=1, name=john_2_3, pic=pic_3.jpg}, {id=4, sex=0, name=john_2_4, pic=pic_4.jpg}]}

6) finally, put the code in the main method into the web layer. You only need to define one query parameter, and it is very easy to set up the query service. The original query interface is still called in dataFetcher

7) introduce maven dependencies


<dependency>
  <groupId>com.graphql-java</groupId>
  <artifactId>graphql-java</artifactId>
  <version>2.0.0</version>
</dependency>

What is the definition of graphql query that might help you

json



{
  id=6, 
  sex=0, 
  name="Name_6", 
  pic="pic_6.jpg"
}

query


{
  id,
  sex,
  name,
  pic
}

The next part, which is essentially the json string, is readable without the = and value

conclusion

graphql took one kind of brand-new way of thinking, can simplify the web api development, need what data designated by the client, the server returns what data, reduce unnecessary traffic transfer, friendly to mobile terminal, also offers a variety of data aggregation query, multiple queries just using a request, not only satisfy api minimum granularity, and meet the needs of the front end, reduce request, improve the performance.

Feeling later can go toward this respect development, great trend is driven.


Related articles: