graphql java中文文档_GraphQL系列四 Java实战入门

本篇主要使用graphql-java来演示如何使用Java来构建GraphQL API,文中使了Gradle作为构建工具,但未使用其特性,因此你也可以使用Maven,只是简单添加依赖即可。主要涉及到枚举(enum)、输入类型(input)、参数(argument)、接口(interface)、联合(union)等服务端,以及客户端查询测试。本例代码存放在 https://github.com/zhaiqianfeng/GraphQL-Demo/tree/master/java

d538d09f11cb4e850d1cc7a3ebb69c99.png

添加依赖

gradle

compile 'com.graphql-java:graphql-java:3.0.0'

maven

com.graphql-java

graphql-java

3.0.0

本文示例使用的构建工具是Gradle。

示例代码结构

示例结构目录如下

├── advance 高级示例

│   ├── GraphQL_argument.java 传入参数示例

│   ├── GraphQL_interface.java 接口示例

│   └── GraphQL_union.java 联合示例

├── get_start 入门示例

│   └── GraphQL_Simple.java 简单入门示例

└── model Java实体

├── Dog4Interface.java 为接口示例准备的Dog实现

├── Dog4Union.java 为联合示例准备的Dog

├── Fish4Interface.java 为接口示例准备的Fish实现

├── Fish4Union.java 为联合示例准备的Fish

├── IAnimal.java 为接口示例准备的Animal接口

└── User.java 为示例准备的User

每个示例基本遵循流程:提供带查询的示例数据-> 定义GrapQL数据类型 -> 定义暴露给客户端的query api和mutaion api -> 创建GraphQL Schema -> 测试输出。

简单示例

示例代码如下

// com.zqf.get_start.GraphQL_Simple

//服务端示例数据

User user=new User();

user.setName("zhaiqianfeng");

user.setSex("男");

user.setIntro("博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3");

//定义GraphQL类型

GraphQLObjectType userType = newObject()

.name("User")

.field(newFieldDefinition().name("name").type(GraphQLString))

.field(newFieldDefinition().name("sex").type(GraphQLString))

.field(newFieldDefinition().name("intro").type(GraphQLString))

.build();

//定义暴露给客户端的查询query api

GraphQLObjectType queryType = newObject()

.name("userQuery")

.field(newFieldDefinition().type(userType).name("user").staticValue(user))

.build();

//创建Schema

GraphQLSchema schema = GraphQLSchema.newSchema()

.query(queryType)

.build();

//测试输出

GraphQL graphQL = GraphQL.newGraphQL(schema).build();

Map result = graphQL.execute("{user{name,sex,intro}}").getData();

System.out.println(result);

执行输出

{user={name=zhaiqianfeng, sex=男, intro=博主,专注于Linux,Java,nodeJs,Web前端:Html5,JavaScript,CSS3}}

参数(argument)示例

定义形参

传输参数是通过argument方法传入并指定类型,如

.argument(newArgument()

.name("id")

.type(new GraphQLNonNull(GraphQLInt)))

接收参数

获取参数使用DataFetchingEnvironment,如

int id=environment.getArgument("id");

获取参数有如下两个重构

Map getArguments();

T getArgument(String name);

但当我使用后者把传入的userInfo转换为User时,异常

java.util.LinkedHashMap cannot be cast to com.zqf.model.User

因此不得不如下蹩脚书写

Map userInfoMap=environment.getArgument("userInfo");

User userInfo=new User();

for (String key : userInfoMap.keySet()){

switch (key){

case "name":

userInfo.setName(userInfoMap.get("name").toString());

break;

case "sex":

userInfo.setSex(userInfoMap.get("sex").toString());

break;

case "intro":

userInfo.setIntro(userInfoMap.get("intro").toString());

break;

case "skills":

ArrayList skillsList=(ArrayList) userInfoMap.get("skills");

String[] skills=new String[skillsList.size()];

userInfo.setSkills(skillsList.toArray(skills));

break;

}

}

Resolver

解析数据使用的是DataFetcher,如

.dataFetcher(new DataFetcher() {

@Override

public Object get(DataFetchingEnvironment environment) {

int id=environment.getArgument("id");

return users.get(id);

}

}))

为了简洁,你可以使用lambda表达式

.dataFetcher(environment -> {

int id=environment.getArgument("id");

return users.get(id);

}))

联合(union)示例

这部分没说明好说的,如果了解了union的概念代码示例非常清晰,请参考github上的源码:GraphQL_union.java。使用GraphQLUnionType定义union类型,其中possibleType指定可以union的类型,重点是关注typeResolver来做类型转换,但个人觉得这里实现有待改进,对于Java这种强类型语言自动处理比较人性化。

GraphQLUnionType animalUnion = newUnionType()//定义联合类型(union)

.name("IAnimal")

.possibleType(dogType)

.possibleType(fishType)

.description("动物联合")

.typeResolver(env -> {

if(env.getObject() instanceof Dog4Union){

return dogType;

}if(env.getObject() instanceof Fish4Union){

return fishType;

}

return null;

})

.build();

接口(interface)示例

graphql-java对GraphQL的接口实现确实使用的Java接口,但个人觉得使用集成或许更合适。定义接口使用的GraphQLInterfaceType关键字,实现接口使用的withInterface关键字。

坑:对象为定义

上面的关键字都不难理解,蛋疼的是把如下的定义放在方法体中却提示为定义

GraphQLInterfaceType animalInterface = newInterface()//定义接口(interface)类型

.name("IAnimal")

.description("动物接口")

.field(newFieldDefinition()

.name("name")

.type(GraphQLString))

.typeResolver(new TypeResolver() {

@Override

public GraphQLObjectType getType(TypeResolutionEnvironment env) {

if (env.getObject() instanceof Dog4Interface) {

return dogType; //提示 dogType 未定义

}

if (env.getObject() instanceof Fish4Interface) {

return fishType; //提示 fishType 未定义

}

return null;

}

})

.build();

GraphQLObjectType dogType = newObject()//定义Dog类型

.name("Dog4Interface")

.field(newFieldDefinition().name("name").type(GraphQLString))

.field(newFieldDefinition().name("legs").type(GraphQLInt))

.withInterface(animalInterface)

.build();

GraphQLObjectType fishType = newObject()//定义Fish类型

.name("Fish4Interface")

.field(newFieldDefinition().name("name").type(GraphQLString))

.field(newFieldDefinition().name("tailColor").type(GraphQLString))

.withInterface(animalInterface)

.build();

Schema加入额外类型

最后还要提示下,由于查询返回的接口,但实现并没有自动添加到Schema中,因此需要在创建Schema时间,将其手动加入

//额外的GraphQL类型

Set types=new HashSet<>();

types.add(dogType);

types.add(fishType);

//创建Schema

GraphQLSchema schema = GraphQLSchema.newSchema()

.query(queryType)

.build(types);

结束语

虽然遇到了许多坑,但最后还是把需要的功能演示出来了,但无论是那种类库,基本的流程一般不会改变:基本遵循流程:定义GrapQL数据类型 -> 定义暴露给客户端的query api和mutaion api -> 创建GraphQL Schema。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
graphql-java 是 GraphQLJava 实现。这个库的目标是用于真实的生产环境。graphql-java 解析和执行查询 GraphQL 。它并不真正获取任何数据的:数据来源于执行回调或提供静态数据。graphql-java 的 "hello world":import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; import static graphql.Scalars.GraphQLString; import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition; import static graphql.schema.GraphQLObjectType.newObject; public class HelloWorld {     public static void main(String[] args) {         GraphQLObjectType queryType = newObject()                         .name("helloWorldQuery")                         .field(newFieldDefinition()                                 .type(GraphQLString)                                 .name("hello")                                 .staticValue("world")                                 .build())                         .build();         GraphQLSchema schema = GraphQLSchema.newSchema()                         .query(queryType)                         .build();         Map result = new GraphQL(schema).execute("{hello}").getData();         System.out.println(result);         // Prints: {hello=world}     } } 标签:graphql
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值