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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM