GraphQL入门总体创建教程

目录

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

    简介 因为目前做的项目查询提供的接口都使用GraphQL替代典型的REST API,所以有必要去对它进行了解和源码的阅读。本篇主要大致了解下GraphQL。
    一种用于API的查询语言,让你的请求数据不多不少。前端按需获取,后端动态返回(不需要的数据不会返回甚至不会查库),对比起典型的REST API将更加灵活,后端代码提供可选能力。如果增加新的字段应用不想处理这部分数据可以不用区分版本。
    后端确定哪些接口行为是被允许的,前端按需获取数据,让你的请求数据不多不少。
    详细的介绍可以参考官方首页配合动图更加清晰。

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

    maven依赖
    4.0.0org.springframework.bootspring-boot-starter-parent2.1.6.RELEASE com.graphql-java.tutorialbook-details0.0.1-SNAPSHOTbook-detailsDemo project for Spring Boot1.8org.springframework.bootspring-boot-starterorg.springframework.bootspring-boot-starter-testtestorg.springframework.bootspring-boot-starter-webcom.graphql-javagraphql-java11.0com.graphql-javagraphql-java-spring-boot-starter-webmvc1.0com.google.guavaguava26.0-jreorg.springframework.bootspring-boot-maven-plugincentralaliyun mavenhttp://maven.aliyun.com/nexus/content/groups/public/defaulttruefalse


    Schema
    src/main/resources中创建schema.graphqls文件:
    type Query {bookById(id: ID): Book}type Book {id: IDname: StringpageCount: Intauthor: Author}type Author {id: IDfirstName: StringlastName: 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; @Componentpublic class GraphQLProvider {private GraphQL graphQL; /*** 注入GraphQL实例,GraphQL Java Spring适配器将使用GraphQL实例使我们的schema可用,通过Http-使用默认的"/graphql"url路径** @return*/@Beanpublic GraphQL graphQL() {return graphQL; }@PostConstructpublic 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(); }@AutowiredGraphQLDataFetchers 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; @Componentpublic class GraphQLDataFetchers {/*** books静态数据*/private static List 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 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 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 get(DataFetchingEnvironment dataFetchingEnvironment) throws Exception; }


    Default DataFetchers
    【GraphQL入门总体创建教程】如上我们实现了两个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中指定的字段相同。

    总体创建过程
    GraphQL入门总体创建教程
    文章图片


    资料 Getting started with Spring Boot
    graphql中文官网
    以上就是GraphQL入门总体创建教程的详细内容,更多关于GraphQL创建教程的资料请关注脚本之家其它相关文章!

      推荐阅读