美文网首页
GraphQL学习,Java简单实现

GraphQL学习,Java简单实现

作者: insomniaLee | 来源:发表于2020-05-07 22:25 被阅读0次

    简介

    是一种查询语言,类似前端与后端之间通过sql语言进行交互。用类似json的语言来查询需要的数据。
    如在以下查询语句

    {
      bookById(id: "1") {
        id
        name
        pageCount
        author {
          name
        }
      }
    }
    

    可以得到一下结果

    {
      "data": {
        "bookById": {
          "id": "1",
          "name": "风雪追击",
          "pageCount": 233,
          "author": {
            "name": "东野圭吾"
          }
        }
      }
    }
    

    maven依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.graphql-java</groupId>
        <artifactId>graphql-java</artifactId>
        <version>11.0</version>
    </dependency>
    <dependency>
        <groupId>com.graphql-java</groupId>
        <artifactId>graphql-java-spring-boot-starter-webmvc</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>26.0-jre</version>
    </dependency>
    

    定义schema

    上面的查询语句我们事先定义了一下schema,放置在src/main/resources/schema.graphqls

    type Query {
      bookById(id: ID): Book
      authors:[Author]
      books:[Book]
      authorAndBooks:[Author]
    }
    
    type Book {
      id: ID
      name: String
      pageCount: Int
      author: Author
    }
    
    type Author {
      id: ID
      name: String
      books:[Book]
    }
    

    其中类型为Query的表示为查询,类似CURD中的R;除了Query还有Mutation来表示对数据进行修改,相当于CURD中的CUD操作。在schema中定义了4跳query语句如上所示。我们还定义了Book和Author的类型,其中Book中包含一个Author,Author中包含Book的列表。

    定义GraphQLProvider

    GraphQLProvider类将会创建一个GraphQL的实例,这里通过@Bean的方式暴露出去可以通过/graphql的url访问到(由依赖graphql-java-spring-boot-starter-webmvc实现的功能)

    @Component
    public class GraphQLProvider {
    
        private GraphQL graphQL;
    
        @Bean
        public GraphQL graphQL() {
            return graphQL;
        }
    
        @Autowired
        GraphQLDataFetchers graphQLDataFetchers;
    
        @PostConstruct
        public void init() throws IOException {
            URL url = Resources.getResource("schema.graphqls");
            String sdl = Resources.toString(url, Charsets.UTF_8);
            GraphQLSchema graphQLSchema = buildSchema(sdl);
            this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
        }
    
        private GraphQLSchema buildSchema(String sdl) {
            TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
            RuntimeWiring runtimeWiring = buildWiring();
            SchemaGenerator schemaGenerator = new SchemaGenerator();
            return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
        }
    
        private RuntimeWiring buildWiring() {
            Map<String, DataFetcher> map = new HashMap<String,DataFetcher>();
            map.put("bookById",graphQLDataFetchers.getBookByIdDataFetcher());
            map.put("books",graphQLDataFetchers.getBooksDataFetcher());
            map.put("authors",graphQLDataFetchers.getAuthorsDataFetcher());
            return RuntimeWiring.newRuntimeWiring()
                    .type(newTypeWiring("Query")
                            .dataFetchers(map))
                    .type(newTypeWiring("Book")
                            .dataFetcher("author", graphQLDataFetchers.getAuthorDataFetcher())
                            .dataFetcher("pageCount",graphQLDataFetchers.getPageCountDataFetcher()))
                    .type(newTypeWiring("Author")
                            .dataFetcher("books",graphQLDataFetchers.getBooksByAUthorDataFetcher()))
                    .build();
        }
    }
    

    DataFetchers

    GraphQL在执行查询时,是通过Datafetcher来获取一个字段的数据。DataFetcher是一个接口

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

    新建一个类用于存放所有的datafetcher(小型项目)

    @Component
    public class GraphQLDataFetchers {
    
        private static List<Map<String, String>> books = Arrays.asList(
                ImmutableMap.of("id", "1",
                        "name", "风雪追击",
                        "totalPages", "233",
                        "authorId", "a1"),
                ImmutableMap.of("id", "4",
                        "name", "解忧杂货店",
                        "totalPages", "342",
                        "authorId", "a1"),
                ImmutableMap.of("id", "2",
                        "name", "达芬奇密码",
                        "totalPages", "635",
                        "authorId", "a2"),
                ImmutableMap.of("id", "3",
                        "name", "大秦帝国",
                        "totalPages", "371",
                        "authorId", "a3")
        );
    
        private static List<Map<String, String>> authors = Arrays.asList(
                ImmutableMap.of("id", "a1",
                        "name", "东野圭吾"),
                ImmutableMap.of("id", "a2",
                        "name", "丹布朗"),
                ImmutableMap.of("id", "a3",
                        "name", "孙皓晖")
        );
    
        public DataFetcher getBookByIdDataFetcher() {
            return dataFetchingEnvironment -> {
                String bookId = dataFetchingEnvironment.getArgument("id");
                return books
                        .stream()
                        .filter(book -> book.get("id").equals(bookId))
                        .findFirst()
                        .orElse(null);
            };
        }
    
        public DataFetcher getAuthorDataFetcher() {
            return dataFetchingEnvironment -> {
                Map<String,String> book = dataFetchingEnvironment.getSource();
                String authorId = book.get("authorId");
                return authors
                        .stream()
                        .filter(author -> author.get("id").equals(authorId))
                        .findFirst()
                        .orElse(null);
            };
        }
    
        public  DataFetcher getBooksByAUthorDataFetcher(){
            return dataFetchingEnvironment -> {
                Map<String,String> author = dataFetchingEnvironment.getSource();
                String authorId = author.get("id");
                return books.stream().filter(book->book.get("authorId").equals(authorId)).toArray();
            };
        }
    
        public  DataFetcher getAuthorTotalCountDataFetcher(){
            return dataFetchingEnvironment -> {
                Map<String,Object> author = dataFetchingEnvironment.getSource();
                String authorId = author.get("id").toString();
                return books.stream().filter(book->book.get("authorId").equals(authorId))
                        .collect(Collectors.summingInt(map->Integer.parseInt(map.get("totalPages"))));
            };
        }
    
        public DataFetcher getAuthorsDataFetcher(){
            return dataFetchingEnvironment->{
                return authors;
            };
        }
        
    
        public DataFetcher getBooksDataFetcher(){
            return dataFetchingEnvironment -> {
                return books;
            };
        }
        
        public DataFetcher getPageCountDataFetcher() {
            return dataFetchingEnvironment -> {
                Map<String,String> book = dataFetchingEnvironment.getSource();
                return book.get("totalPages");
            };
        }
    }
    

    验证

    可以使用graphql-playground工具来进行验证。我电脑的版本是macos10.15.4,使用1.8.9可以运行,1.8.10则会报错,使用前需要在顶栏输入http://localhost:8080/graphql,然后在左边输入查询语句,右边就能得到查询结果。

    image.png

    参考链接

    java搭建graphQL demo

    相关文章

      网友评论

          本文标题:GraphQL学习,Java简单实现

          本文链接:https://www.haomeiwen.com/subject/txhtnhtx.html