热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

graphqljavademo_GraphQL实战第二篇java实现及分析

GraphQL实战-第二篇-java实现及分析到这里必须具备的知识储备:对GraphQL有简单的了解,了解Schema的常用类型。这里用一些demo示例

GraphQL实战-第二篇-java实现及分析

到这里必须具备的知识储备:对GraphQL有简单的了解,了解Schema的常用类型。

这里用一些demo示例来体验GraphQL的执行过程,这只是借助graphql-java实现的java版本。

首先需要引入graphql-java的依赖

com.graphql-java

graphql-java

15.0

Demo1

第一个demo是官网提供的

import graphql.ExecutionResult;

import graphql.GraphQL;

import graphql.schema.GraphQLSchema;

import graphql.schema.StaticDataFetcher;

import graphql.schema.idl.RuntimeWiring;

import graphql.schema.idl.SchemaGenerator;

import graphql.schema.idl.SchemaParser;

import graphql.schema.idl.TypeDefinitionRegistry;

import static graphql.schema.idl.RuntimeWiring.newRuntimeWiring;

public class HelloWorld {

public static void main(String[] args) {

//定义schema文件,直接写在了代码中,包含一个hello的查询方法

String schema = "type Query{hello: String} schema{query: Query}";

SchemaParser schemaParser = new SchemaParser();

//直接加载schema,初始化GraphQL

TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);

//加载一份服务端数据

RuntimeWiring runtimeWiring = new RuntimeWiring()

.type("Query", builder -> builder.dataFetcher("hello", new StaticDataFetcher("world")))

.build();

SchemaGenerator schemaGenerator = new SchemaGenerator();

GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);

// 构建一个GraphQL实例,执行graphql脚本

GraphQL build = GraphQL.newGraphQL(graphQLSchema).build();

ExecutionResult executionResult = build.execute("{hello}");

System.out.println(executionResult.getData().toString());

// Prints: {hello=world}

}

}

这个demo直接加载了schema的内容,构建Graphql执行脚本。这种方式最接近于实际开发的操作。

Deom2

通过这个demo来看一下一个GraphQL的服务端都做了什么。并对比一下java代码加载GraphQL对象与schema中的GraphQL的联系。

所依赖的对象User

/**

* ClassName: User

* Description:

* date: 2019/6/28 10:38 AM

*

* @author chengluchao

* @since JDK 1.8

*/

@Data

public class User {

private int age;

private long id;

private String name;

private Card card;

public User(int age, long id, String name, Card card) {

this.age = age;

this.id = id;

this.name = name;

this.card = card;

}

public User(int age, long id, String name) {

this.age = age;

this.id = id;

this.name = name;

}

}

/**

* ClassName: Card

* Description:

* date: 2019/6/28 3:25 PM

*

* @author chengluchao

* @since JDK 1.8

*/

@Data

public class Card {

private String cardNumber;

private Long userId;

public Card(String cardNumber, Long userId) {

this.cardNumber = cardNumber;

this.userId = userId;

}

}

接下来是demo

/**

* ClassName: GraphQLDemo

* Description:

* date: 2019/6/28 10:40 AM

*

* @author chengluchao

* @since JDK 1.8

*/

public class GraphQLDemo {

public static void main(String[] args) {

/*

定义GraphQL对象,等同于schema中定义的

type User {

id:ID

age:Int

name:String

}

*/

GraphQLObjectType userObjectType = GraphQLObjectType.newObject()

.name("User")

.field(GraphQLFieldDefinition.newFieldDefinition().name("id").type(Scalars.GraphQLLong))

.field(GraphQLFieldDefinition.newFieldDefinition().name("age").type(Scalars.GraphQLInt))

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

.build();

/*

queryUser : User 指定对象及参数类型

等同于在GraphQL中定义一个无参方法 queryUser,返回值为User

queryUser:User

dataFetcher指定了响应的数据集,这个demo里使用了静态写入的方式

*/

GraphQLFieldDefinition userFileldDefinition = GraphQLFieldDefinition.newFieldDefinition()

.name("queryUser")

.type(userObjectType)

//静态数据

.dataFetcher(new StaticDataFetcher(new User(19, 2, "CLC")))

.build();

/*

type UserQuery 定义查询类型

对应的graphQL为:

type UserQuery {

queryUser:User

}

*/

GraphQLObjectType userQueryObjectType = GraphQLObjectType.newObject()

.name("UserQuery")

.field(userFileldDefinition)

.build();

/*

Schema 定义查询

定义了query的root类型

对应的GraphQL语法为:

schema {

query:UserQuery

}

*/

GraphQLSchema qlSchema = GraphQLSchema.newSchema().query(userQueryObjectType).build();

//构建一个GraphQl对象,执行逻辑都在此处进行

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

//模拟客户端传入查询脚本,方法名queryUser,获取响应值为 id name age

String query = "{queryUser{id name age}}";

// 执行业务操作逻辑,获取返回值

ExecutionResult result = graphQL.execute(query);

System.out.println(result.toSpecification());

}

}

这里对应的sehema应该是这样的:

#对应的User定义如下

schema {

#定义查询

query: UserQuery

}

#定义查询类型

type UserQuery {

#指定对象以及参数类型

queryUser : User

}

#定义对象

type User {

#!表示非空

id: ID!

name:String

age:Int

card:Card

}

type Card {

cardNumber:String

userId:ID

}

可以看出:

schema的结构层级是:schema > UserQuery > User

schema中定义的是操作类型,UserQuery下定义的是操作方法,而User对应的是GraphQL的对象,此对象应该对应于java中一个相同的对象

以上demo实现中有两点是实战中不可取的:

schema的加载方式,应该以读取本地配置的形式加载

dataFetcher的数据加载,demo中是静态写死的方式,实战中应该是动态加载的数据

接下来从这两点改进

demo3

首先在resources目录下创建一个user.graphqls的文件

#对应的User定义如下

schema {

#定义查询

query: UserQuery

}

#定义查询类型

type UserQuery {

#指定对象以及参数类型

queryUser : User

queryUserById(id:ID) : User

}

#定义对象

type User {

#!表示非空

id: ID!

name:String

age:Int

card:Card

}

type Card {

cardNumber:String

userId:ID

}

import clc.bean.Card;

import clc.bean.User;

import graphql.ExecutionResult;

import graphql.GraphQL;

import graphql.schema.GraphQLSchema;

import graphql.schema.idl.RuntimeWiring;

import graphql.schema.idl.SchemaGenerator;

import graphql.schema.idl.SchemaParser;

import graphql.schema.idl.TypeDefinitionRegistry;

import org.apache.commons.io.IOUtils;

/**

* ClassName: GraphQLSDLDemo

* Description:

* date: 2019/6/28 11:19 AM

*

* @author chengluchao

* @since JDK 1.8

*/

public class GraphQLSDLDemo {

public static void main(String[] args) throws Exception {

//读取graphqls文件

String fileName = "user.graphqls";

String fileContent = IOUtils.toString(GraphQLSDLDemo.class.getClassLoader().getResource(fileName), "UTF-8");

//解析文件

TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(fileContent);

RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring()

.type("UserQuery", builder ->

builder.dataFetcher("queryUserById", environment -> {

//解析请求参数,根据业务返回结果

Long id = Long.parseLong(environment.getArgument("id"));

Card card = new Card("123456", id);

return new User(18, id, "user0" + id, card);

})

)

.build();

GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, wiring);

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

String query = "{queryUserById(id:15){id,name,age,card{cardNumber,userId}}}";

ExecutionResult result = graphQL.execute(query);

System.out.println("query: " + query);

System.out.println(result.toSpecification());

}

}

从demo升级成实战项目需要做的内容:

schema与java代码分离,可以通过读取文件的形式将schema加载到系统中;

动态处理GraphQL的请求参数,并随之生成对应的响应

可能大家已经发现,入参和出参都需要服务端编码实现解析。

其实graphql-java做的事情是很有限的,主要作用如下:

维护schema的结构

根据GraphQL的脚本需要,过滤响应结果

其他很大一部分的工作都需要自己实现的。

CLC



推荐阅读
  • Lua基本语法lua与C#的交互(相当简单详细的例子)
    lua脚本与C#的交互本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验——高分辨率用户请根据需求调整网页缩放比例)1LuaAndC#——L ... [详细]
  • 正在学习操作系统开发,遇到一个内核在GRUB Legacy(0.97)中无法成功引导的问题。具体表现为输入内核命令后显示错误信息,尝试引导时GRUB挂起。 ... [详细]
  • 本文总结了几个常用的Android开发技巧,包括检测设备上是否安装特定应用、获取应用的版本名称、设置状态栏透明以及如何从一个应用跳转至另一个应用的方法。 ... [详细]
  • 本文介绍如何使用Java实现AC自动机(Aho-Corasick算法),以实现高效的多模式字符串匹配。文章涵盖了Trie树和KMP算法的基础知识,并提供了一个详细的代码示例,包括构建Trie树、设置失败指针以及执行搜索的过程。 ... [详细]
  • Java 中静态和非静态嵌套类的区别 ... [详细]
  • 使用EF Core在.Net Core控制台应用中操作SQLite数据库
    本文介绍如何利用Visual Studio 2019和Windows 10环境,通过Entity Framework Core(EF Core)实现对SQLite数据库的读写操作。项目源代码可从百度网盘下载。 ... [详细]
  • Unity3D入门:实现模型手势操作
    本文主要介绍如何在Unity3D中导入模型并实现基本的手势操作功能,包括模型的旋转、缩放等。通过简单的步骤,帮助初学者快速掌握Unity3D中的模型操作技巧。 ... [详细]
  • 设计模式系列-原型模式
    一、上篇回顾上篇创建者模式中,我们主要讲述了创建者的几类实现方案,和创建者模式的应用的场景和特点,创建者模式适合创建复杂的对象,并且这些对象的每个组成部分的详细创建步骤可以是动态的变化的,但 ... [详细]
  • Nibblestutotials.net教程 – Blend  Silverlight1系列之Button Basic
    Basic:createonebutton文中三部分所用资源及代码下载:part1,part2,part3Buttonsbasicpart1:drawingNibbl ... [详细]
  • 本文旨在探讨计算机机房的有效管理与维护方法,包括合理的机房布局设计、高效的操作系统安装与恢复技术以及数据保护措施。随着信息技术教育的发展,计算机机房作为教学的重要组成部分,其稳定性和安全性直接影响到教学质量。文章分析了当前机房管理中存在的问题,并提出了针对性的解决方案。 ... [详细]
  • 深入解析Spring Boot项目的启动机制
    在Java后端开发中,Spring Boot框架以其简洁性和强大的功能受到了广泛欢迎。本文将探讨Spring Boot项目启动的核心——SpringApplication类及其run()方法的工作原理。 ... [详细]
  • 深入理解Java类加载机制及安全防护
    本文探讨了Java类加载的过程,包括加载、验证、准备、解析和初始化五个阶段,并详细解释了每个阶段的具体操作和意义。此外,文章还讨论了Java如何通过双亲委派模型来保障核心API的安全性,以及在特定情况下如何打破这一机制。 ... [详细]
  • 将数组的所有元素递增 1 的 Java 程序 ... [详细]
  • 本文介绍了一种算法,用于在一个给定的二叉树中找到一个节点,该节点的子树包含最大数量的值小于该节点的节点。如果存在多个符合条件的节点,可以选择任意一个。 ... [详细]
  • 【Java数据结构和算法】008栈
    目录0、警醒自己一、栈的应用场景和介绍1、栈的应用场景一个实际的场景:我的思考:2、栈的介绍入栈演示图:出栈演示图 ... [详细]
author-avatar
woooooso_776
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有