zoukankan      html  css  js  c++  java
  • GraphQL实战-第三篇-spring Boot 实现

    GraphQL实战-第三篇-spring Boot 实现

    https://blog.csdn.net/xplan5/article/details/108748939

    在上一篇的java实现中,分享了使用GraphQL的基本流程,接下来分享一下在Spring Boot中对GraphQL的应用

    首先创建一个Spring Boot的项目

    POM依赖

    <?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.3.4.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    	<groupId>com.clc</groupId>
    	<artifactId>boot</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>boot</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-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>com.graphql-java</groupId>
    			<artifactId>graphql-java</artifactId>
    			<version>15.0</version>
    		</dependency>
    		<!--lombok-->
    		<dependency>
    			<groupId>org.projectlombok</groupId>
    			<artifactId>lombok</artifactId>
    			<version>1.18.4</version>
    		</dependency>
    
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    </project>
    

    创建schema

    接下来就是创建一个schema的文件,来写graphql的定义,这里还用之前的例子。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
    }
    

    Java实现

    数据操作对应的java对象

    package com.clc.boot.bean;
    
    import lombok.Data;
    
    /**
     * ClassName: User<br/>
     * Description: <br/>
     * date: 2019/6/28 10:38 AM<br/>
     *
     * @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;
        }
    }
    
    package com.clc.boot.bean;
    
    import lombok.Data;
    
    /**
     * ClassName: Card<br/>
     * Description: <br/>
     * date: 2019/6/28 3:25 PM<br/>
     *
     * @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;
        }
    }
    

    解析GraphQL的核心类

    package com.clc.boot.graphql;
    
    import com.clc.boot.bean.User;
    import com.clc.boot.bean.Card;
    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.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ResourceUtils;
    
    import javax.annotation.PostConstruct;
    import java.io.File;
    import java.io.IOException;
    
    /**
     * 实现功能:将GraphQL对象载入待Spring容器,并且完成GraphQL对象初始化的功能
     *
     * @author chengluchao
     */
    @Component
    public class GraphQLProvider {
    
    
        private GraphQL graphQL;
    
        @Bean
        public GraphQL graphQL() {
            return graphQL;
        }
    
        /**
         * 加载schema
         *
         * @throws IOException
         */
        @PostConstruct
        public void init() throws IOException {
            File file = ResourceUtils.getFile("classpath:user.graphqls");
            GraphQLSchema graphQLSchema = buildGraphQLSchema(file);
            this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
        }
    
        private GraphQLSchema buildGraphQLSchema(File file) {
            TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(file);
            GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeRegistry, buildWiring());
            return graphQLSchema;
        }
    
        private GraphQLSchema buildSchema(String sdl) {
            TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
            RuntimeWiring runtimeWiring = buildWiring();
            SchemaGenerator schemaGenerator = new SchemaGenerator();
            return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
        }
    
        /**
         * 业务实现,demo版
         * 如果是开发实战,这一点的设计是重点,需要考虑如何根据graphql中定义的方法来执行java代码
         *
         * @return
         */
        private RuntimeWiring buildWiring() {
            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();
            return wiring;
        }
    }
    

    接下来是GraphQL的入口:

    package com.clc.boot.controller;
    
    import graphql.ExecutionResult;
    import graphql.GraphQL;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    
    /**
     * ClassName: GraphQLController<br/>
     * Description: <br/>
     * date: 2019/6/28 5:38 PM<br/>
     *
     * @author chengluchao
     * @since JDK 1.8
     */
    @RequestMapping("graphql")
    @Controller
    public class GraphQLController {
        @Autowired
        private GraphQL graphQL;
    
        @RequestMapping("query")
        @ResponseBody
        public Object query(@RequestParam("query") String query) {
            ExecutionResult result = this.graphQL.execute(query);
            return result.toSpecification();
        }
    }
    
    

    测试:

    127.0.0.1:8080/graphql/query?query={ user: queryUserById(id:15){id,name,age,card{cardNumber,userId}}}

    {
        "data": {
            "user": {
                "id": "15",
                "name": "user015",
                "age": 18,
                "card": {
                    "cardNumber": "123456",
                    "userId": "15"
                }
            }
        }
    }
    

    源码地址:https://gitee.com/chengluchao/graphql-clc/tree/master/graphql-springboot

    这里实现了graphql在spring-boot中的应用,由于解析graphql到业务执行还不够自动化,所以此例子还是一个demo级别

    CLC

  • 相关阅读:
    ETL概念集锦
    想要快速泡大麦茶的4种方法
    Suggest blowing out the dust
    Pessimistic and optimistic locking
    操作系统简介
    初学计算机基础
    JavaScript筑基篇(三)->JS原型和原型链的理解
    网页瀑布流效果实现的几种方式
    javascript的基本语法、数据结构
    javascript如何列出全局对象的非原生属性。
  • 原文地址:https://www.cnblogs.com/chenglc/p/13743773.html
Copyright © 2011-2022 走看看