GraphQL実戦-第3編-spring Boot実現


GraphQL実戦-第3編-spring Boot実現
前回のjava実装では、GraphQLを使用するための基本的な流れを共有し、次にSpring BootでのGraphQLへの応用を共有しました
まずSpring Bootのプロジェクトを作成します
POM依存


	4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		2.3.4.RELEASE
		 
	
	com.clc
	boot
	0.0.1-SNAPSHOT
	boot
	Demo project for Spring Boot

	
		1.8
	

	
		
			org.springframework.boot
			spring-boot-starter
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			com.graphql-java
			graphql-java
			15.0
		
		
		
			org.projectlombok
			lombok
			1.18.4
		

	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	



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
* Description:
* date: 2019/6/28 10:38 AM
* * @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
* Description:
* date: 2019/6/28 3:25 PM
* * @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
* Description:
* date: 2019/6/28 5:38 PM
* * @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ここではspring-bootにおけるgraphqlの応用を実現したが,graphqlのビジネス実行への解析はまだ自動化されていないため,この例はdemoレベルである.
CLC