GraphQL入门总体创建教程

目录
  • 简介
  • 简单示例
    • maven依赖
    • Schema
    • 解析schema并关联对应的fetchers
    • DataFetchers
    • Default DataFetchers
    • 总体创建过程
  • 资料

简介

因为目前做的项目查询提供的接口都使用GraphQL替代典型的REST API,所以有必要去对它进行了解和源码的阅读。本篇主要大致了解下GraphQL。

一种用于API的查询语言,让你的请求数据不多不少。前端按需获取,后端动态返回(不需要的数据不会返回甚至不会查库),对比起典型的REST API将更加灵活,后端代码提供可选能力。如果增加新的字段应用不想处理这部分数据可以不用区分版本。

后端确定哪些接口行为是被允许的,前端按需获取数据,让你的请求数据不多不少。

详细的介绍可以参考官方首页配合动图更加清晰。

简单示例

最好使用Spring Initializr去创建一个新的项目,不会产生一些冲突。

maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.graphql-java.tutorial</groupId>
    <artifactId>book-details</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>book-details</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java -->
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-java</artifactId>
            <version>11.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.graphql-java/graphql-java-spring-boot-starter-webmvc -->
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-java-spring-boot-starter-webmvc</artifactId>
            <version>1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>26.0-jre</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>central</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <layout>default</layout>
            <!-- 是否开启发布版构件下载 -->
            <releases>
                <enabled>true</enabled>
            </releases>
            <!-- 是否开启快照版构件下载 -->
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

Schema

src/main/resources中创建schema.graphqls文件:

type Query {
    bookById(id: ID): Book
}
type Book {
    id: ID
    name: String
    pageCount: Int
    author: Author
}
type Author {
    id: ID
    firstName: String
    lastName: String
}

可以看到定义了一个bookById查询,用于根据id查询书籍,书籍中包含id、name、pageCount、author属性,其中author是一个复合类型所以定义了type Author

上面显示的用于描述schema的特定于域的语言称为schema定义语言或SDL。更多细节可以在这里找到。

解析schema并关联对应的fetchers

一旦我们有了这个文件,我们需要通过读取文件并解析它并且添加代码来为它获取数据使它“栩栩如生”。

package com.graphqljava.tutorial.bookdetails;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URL;
import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring;
@Component
public class GraphQLProvider {
    private GraphQL graphQL;
    /**
     * 注入GraphQL实例,GraphQL Java Spring适配器将使用GraphQL实例使我们的schema可用,通过Http-使用默认的"/graphql"url路径
     *
     * @return
     */
    @Bean
    public GraphQL graphQL() {
        return graphQL;
    }
    @PostConstruct
    public void init() throws IOException {
        //使用Resources读取graphqls文件
        URL url = Resources.getResource("schema.graphqls");
        //拿到graphqls文件内容
        String sdl = Resources.toString(url, Charsets.UTF_8);
        GraphQLSchema graphQLSchema = buildSchema(sdl);
        this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
    }
    @Autowired
    GraphQLDataFetchers graphQLDataFetchers;
    /**
     * 创建GraphQLSchema实例:解析schema并关联fetcher
     *
     * @param sdl
     * @return
     */
    private GraphQLSchema buildSchema(String sdl) {
        TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
        RuntimeWiring runtimeWiring = buildWiring();
        SchemaGenerator schemaGenerator = new SchemaGenerator();
        return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
    }
    /**
     * 根据层级去关联fetcher构建RuntimeWiring。最外层为Query可以提供bookById所需参数。第二层为Book-经过第一层获得的,可以为author提供所需参数。
     *
     * @return
     */
    private RuntimeWiring buildWiring() {
        return RuntimeWiring.newRuntimeWiring()
                .type(newTypeWiring("Query")
                        .dataFetcher("bookById", graphQLDataFetchers.getBookByIdDataFetcher()))
                .type(newTypeWiring("Book")
                        .dataFetcher("author", graphQLDataFetchers.getAuthorDataFetcher()))
                .build();
    }
}
package com.graphqljava.tutorial.bookdetails;
import com.google.common.collect.ImmutableMap;
import graphql.schema.DataFetcher;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Component
public class GraphQLDataFetchers {
    /**
     * books静态数据
     */
    private static List<Map<String, String>> books = Arrays.asList(
            ImmutableMap.of("id", "book-1",
                    "name", "Harry Potter and the Philosopher's Stone",
                    "pageCount", "223",
                    "authorId", "author-1"),
            ImmutableMap.of("id", "book-2",
                    "name", "Moby Dick",
                    "pageCount", "635",
                    "authorId", "author-2"),
            ImmutableMap.of("id", "book-3",
                    "name", "Interview with the vampire",
                    "pageCount", "371",
                    "authorId", "author-3")
    );
    /**
     * autors静态数据
     */
    private static List<Map<String, String>> authors = Arrays.asList(
            ImmutableMap.of("id", "author-1",
                    "firstName", "Joanne",
                    "lastName", "Rowling"),
            ImmutableMap.of("id", "author-2",
                    "firstName", "Herman",
                    "lastName", "Melville"),
            ImmutableMap.of("id", "author-3",
                    "firstName", "Anne",
                    "lastName", "Rice")
    );
    /**
     * bookById的fetcher,这里只是简单的通过静态数据进行筛选,具体生产使用sql进行查询
     *
     * @return
     */
    public DataFetcher getBookByIdDataFetcher() {
        return dataFetchingEnvironment -> {
            // 获得查询筛选参数
            String bookId = dataFetchingEnvironment.getArgument("id");
            return books
                    .stream()
                    .filter(book -> book.get("id").equals(bookId))
                    .findFirst()
                    .orElse(null);
        };
    }
    /**
     * 第二层author fetcher
     *
     * @return
     */
    public DataFetcher getAuthorDataFetcher() {
        return dataFetchingEnvironment -> {
            //获得上级对象
            Map<String, String> book = dataFetchingEnvironment.getSource();
            //根据上级对象找到关联id(相当于外键)
            String authorId = book.get("authorId");
            return authors
                    .stream()
                    .filter(author -> author.get("id").equals(authorId))
                    .findFirst()
                    .orElse(null);
        };
    }
}

DataFetchers

对于GraphQL Java服务器来说,最重要的概念可能是DataFetcher:DataFetcher在执行查询时获取一个字段的数据。

GraphQL Java在执行查询时,会为查询中遇到的每个字段调用相应的DataFetcher。DataFetcher是函数接口,函数具有一个参数为DataFetchingEnvironment类型。

public interface DataFetcher<T> {
T get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception;
}

Default DataFetchers

如上我们实现了两个DataFetchers。如上所述,如果你不指定一个,PropertyDataFetcher则是被默认使用。比如上面的例子中Book.id,Book.name,Book.pageCount,Author.id,Author.firstName和Author.lastName都有一个PropertyDataFetcher与之关联。

PropertyDataFetcher尝试以多种方式查找Java对象的属性。如果是java.util.Map,简单的通过key查找。这对我们来说非常好,因为book和author Maps的keys与schema中指定的字段相同。

总体创建过程

资料

Getting started with Spring Boot

graphql中文官网

以上就是GraphQL入门总体创建教程的详细内容,更多关于GraphQL创建教程的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java 通过API操作GraphQL

    GraphQL可以通过Java的API来实现数据的查询,通过特定的SDL查询语句,获取特定的查询数据.相当于后端作为提供数据源的"数据库",前端根据定义的SDL语句查询需要的数据,将查询数据的控制权交给前端,提高后端接口的通用性和灵活性 引入依赖 <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java</artifactId> <

  • 利用Spring Boot和JPA创建GraphQL API

    目录 一.生成项目 1. 添加依赖项 二.Schema 三.Entity 和 Repository 四.Queries & Exceptions 1. 查询 2. Mutator 3. Exceptions 前言: GraphQL既是API查询语言,也是使用当前数据执行这些查询的运行时.GraphQL让客户能够准确地要求他们所需要的东西,仅此而已,使API随着时间的推移更容易发展,并通过提供API中数据的清晰易懂的描述,支持强大的开发工具. 在本文中,我们将创建一个简单的机场位置应用程序. 一.

  • 从Hello World开始理解GraphQL背后处理及执行过程

    目录 前言 Hello World SchemaParser Parser#parseDocument RuntimeWiring RuntimeWiring.Builder#type GraphQL build execute Execution#execute AsynExecutionStrategy#execute ExecutionStrategy#resolveFieldWithInfo 总体执行过程 前言 在上篇文章<初识GraphQL>中我们大致的了解了GraphQL作用,并通

  • Java 使用 Graphql 搭建查询服务详解

    背景 随着React的开源,facebook相继开源了很多相关的项目,这些项目在他们内部已经使用了多年,其中引起我注意的就是本次讨论的是graphql,目前官方只有nodejs版,由于很多公司的后台技术栈都是Java,所以便有了graphql的java版实现,在github上可以找到,废话不多说,直接看代码吧,具体介绍还是去看官网吧,不然就跑题了. GraphQLSchema Schema相当于一个数据库,它有很多GraphQLFieldDefinition组成,Field相当于数据库表/视图,

  • vue中使用GraphQL的实例代码

    上篇给大家介绍了Java 使用 Graphql 搭建查询服务详解.这里我们讲讲如何在Vue中使用GraphQL. 1. 初始化vue项目 npm install -g @vue/cli vue create vue-apollo-demo 选择默认cli的默认模板就可以了 添加 /src/graphql/article.js . /src/utils/graphql.js 两个文件. ├── node_modules └── public │ ├── favicon.ico │ └── inde

  • GraphQL入门总体创建教程

    目录 简介 简单示例 maven依赖 Schema 解析schema并关联对应的fetchers DataFetchers Default DataFetchers 总体创建过程 资料 简介 因为目前做的项目查询提供的接口都使用GraphQL替代典型的REST API,所以有必要去对它进行了解和源码的阅读.本篇主要大致了解下GraphQL. 一种用于API的查询语言,让你的请求数据不多不少.前端按需获取,后端动态返回(不需要的数据不会返回甚至不会查库),对比起典型的REST API将更加灵活,后

  • MyBatis-Plus 快速入门案例(小白教程)

    一.引言 学习MyBatis-Plus前提需要掌握:数据库相关操作.java等相关知识,最好熟悉Mybatis. 那么本章就来讲解快速搭建MyBatis-Plus开发环境以及对数据库实际操作. 二.准备工作 步骤一:使用IDEA快速搭建SpringBoot项目,填写相关信息即可. 步骤二:引入所需要maven依赖,小编这里有使用lombok依赖,有不了解的小伙伴可以自行学习一下,很简单的. <!--lombok--> <dependency> <groupId>org.

  • IDEA使用入门小白操作教程

    初识IDEA IDEA 全称IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE支持.Ant.JUnit.CVS整合.代码审查. 创新的GUI设计等方面的功能可以说是超常的.IDEA是JetBrains公司的产品. 作为一名合格的程序猿,对于开发工具的选择也是很重要的,虽然我们常用 eclipse.myeclipse等开发工具就能满足目前的开发需求,毕竟每个公司的要求不一样,对于IDE

  • Java 代码检查工具之PMD入门使用详细教程

    介绍 PMD是一个静态源代码分析器.它发现了常见的编程缺陷,如未使用的变量.空捕获块.不必要的对象创建等等. 官网:点这里 官方文档:点这里 使用方式 1.使用插件的方式 下载:File -> Settings -> Plugins -> Marketplace 搜索 "PMDPlugin" ,下载插件. 使用方法:在代码编辑框或Project 窗口的文件夹.包.文件右键,选择"Run PMD"->"Pre Defined"

  • C语言文件操作的入门详解教程

    一.一些需要掌握的知识点 文件有千千万万,但是在我们的程序设计当中,我们谈的文件一般有两种: 1.程序文件 包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe). 2.数据文件 文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件. 而在本节中,我们主要提到的是数据文件. 1.文件名 我们知道,名字都是用来标识和区别事物的,那么文件名也是这样,是区别各个文件的标识. 一个文件

  • C/C++ 开发神器CLion使用入门超详细教程

    CLion是Jetbrains公司旗下新推出的一款专为开发C/C++所设计的跨平台IDE,它是以IntelliJ为基础设计的,同时还包含了许多智能功能来提高开发人员的生产力. Clion2020.2.x最新激活码破解版附安装教程(Mac Linux Windows) https://www.jb51.net/article/200548.htm 同样支持python哦,相信使用过IntelliJ idea开发过java的盆友都很清楚该IDE的强大,所以做为Jetbrains旗下的c/c++开发工

  • python开发之Docker入门安装部署教程

    一.安装Docker 安装环境: 系统:CentOS Linux7 x86_64 安装脚本 wget -qO- https://get.docker.com/ | sh 回车后系统就开始安装docker 安装完成后可以通过以下脚本查看安装结果 docker --version 通过上面的脚本可以查看当前docker的版本,若出现版本信息则说明安装成功 docker system info 执行上面脚本如果出现"Cannot connect to the Docker daemon at"

  • C语言文件操作零基础新手入门保姆级教程

    目录 一.前言 二.文件操作基础知识 ①什么是文件 ②数据文件类型 ③数据如何存储 ④如何读取二进制文件 ⑤什么是文件名 ⑥文件缓冲区 ⑦文件指针 三.文件操作函数 ①fopen 与 fclose ②fputc与fgetc ③fputs与fgets ④fprintf与fscanf ⑤fwrite与fread ⑥fseek与ftell与rewind ⑦ferror与feof ⑧补充函数 sscanf sprintf ⑨补充函数perror  strerror 总结 一.前言 我们如何使我们设计的程

  • Tomcat服务器入门超详细教程

    目录 一,Tomcat的一些概念 –1,服务器 –2,web服务器 –3,Tomcat服务器 二,使用Tomcat –1,下载安装 –2,启动&关闭 –3,测试 三,Tomcat目录结构 –1,核心目录 –2,修改默认端口号8080 四,访问自己的项目资源 –1,在webapps中添加自己简单的项目 –2,测试 –3,一个完整的web应用结构 五,在IDEA中整合Tomcat –1,操作如下图 –2,测试 一,Tomcat的一些概念 –1,服务器 服务器:分为服务器硬件和服务器软件.在硬件服务器

  • 详谈Ubuntu PowerShell(小白入门必看教程)

    早在去年八月份PowerShell就开始开源跨平台了,但是一直没有去尝试,叫做PowerShell Core. 这里打算简单介绍一下如何安装和简单使用,为还不知道PowerShell Core on Ubuntu的同学们提供一点小小的入门帮助,谢谢大家支持~ PowerShell Core是由Microsoft开发的运行在.Net Core上的开源跨平台的任务自动化和配置管理系统. 1.在Ubuntu 16.04上安装PowerShell Core a)导入公共存储库GPG秘钥 curl htt

随机推荐