Aprendizaje inicial del lenguaje de consulta de la interfaz GraphQL

Un lenguaje de consulta para tu API

Recientemente, la compañía usa a menudo esta cosa. Aprendí algo por interés y lo registré de la siguiente manera. Si algo está mal, espero que pueda darme más consejos.

I. Resumen

GraphQL es un lenguaje de consulta para api, una forma de consultar datos existentes cuando el proyecto se está ejecutando. GraphQL proporciona una descripción completa y comprensible de los datos en la API, permite a los clientes pedir lo que realmente necesitan, facilita la evolución de la API con el tiempo y admite potentes herramientas de desarrollo.

APIJson se puede comparar al mismo nivel. Personalmente, creo que apiJson es más práctico y simple en el desarrollo de Java. Por ejemplo, la verificación de permisos puede agregar roles a los permisos de operación de la tabla a través del modelo de anotación @ MethodAccess y admitir llamadas de funciones remotas. En contraste, la dificultad y el costo de aprendizaje de graphql Y el estándar es relativamente alto. Pero si tienes demasiada habilidad, echemos un vistazo hoy.
(El sentimiento personal de APIjson puede referirse al blog, me siento bastante bien https://blog.csdn.net/u014618954/article/details/107021638/)

Dos pantallas preliminares

Graphql es un lenguaje de consulta api, que hace que el desarrollo sea más eficiente y conveniente hasta cierto punto. El siguiente es un ejemplo.
Por ejemplo, los usuarios de un servicio GraphQL que inician sesión para decirnos (yo) así como el nombre del usuario pueden verse así:
① crear
tipos y campos definidos en estos tipos y proporcionar funciones de cada tipo para cada campo.

type Query {
  me: User
}
 
type User {
  id: ID
  name: String
}
function Query_me(request) {
  return request.auth.user;
}
 
function User_name(user) {
  return user.getName();
}

②Query

{
  me {
    name
  }
}

③Atrás

{
  "me": {
    "name": "Luke Skywalker"
  }
}

Lo anterior es una consulta query, puedes consultar todos los nombres de los nombres correspondientes según el nombre, así como las ventajas de consultar por tipo, múltiples parámetros, etc., no mucho que decir, puedes consultar el documento oficial de graphql. La explicación simple se divide en tres puntos, de la siguiente manera.

Escenarios de aplicación :
① Redundancia de campo debido a múltiples plataformas y otras razones
② Múltiples llamadas para agregar datos en una página
③ Cambios frecuentes de interfaz y lógica simplificada

Tres aplicaciones prácticas

Después de hablar de ello durante mucho tiempo, vamos a buscar algunos productos secos. Esta vez demostramos el uso básico de Java y listo.

3.1 java + spring boot + graphql

Nuestra aplicación de muestra será una API simple para obtener la información detallada de un libro específico.

① Construye el directorio

Select:
	Gradle Project
	Java
	Spring Boot 2.1.x
Project metadata
	Group: com.graphql-java.tutorial
	Artifact: book-details
Dependency
	web

② Agregar dependencias básicas


com.graphql-java:graphql-java:11.0 // NEW
com.graphql-java:graphql-java-spring-boot-starter-webmvc:1.0 // NEW
com.google.guava:guava:26.0-jre // NEW
org.springframework.boot:spring-boot-starter-web
org.springframework.boot:spring-boot-starter-test
}

③ Cree archivos relacionados
Cree schema.graphqls en el directorio src / main / resources

//该部分是一个关于书籍的基本类型的定义,并与后续类型的查询有关
type Query {
  bookById(id: ID): Book 
}

type Book {
  id: ID
  name: String
  pageCount: Int
  author: Author
}

type Author {
  id: ID
  firstName: String
  lastName: String
}

Cree GraphQLProvider.class en el directorio com.graphqljava.tutorial.bookdetails y cree una instancia de GraphQL:

@Component
public class GraphQLProvider {

    private GraphQL graphQL;

    @Bean
    public GraphQL graphQL() { 
        return graphQL;
      //  这个GraphQL实例通过使用@Bean注释的GraphQL()方法公开为一个Spring Bean
    }

    @PostConstruct
    public void init() throws IOException {
   		 //使用Guava资源从类路径读取文件
        URL url = Resources.getResource("schema.graphqls");
        //GraphQL Java Spring适配器将使用该GraphQL实例使我们的模式通过HTTP在默认url / 
        String sdl = Resources.toString(url, Charsets.UTF_8);
        //创建一个GraphQLSchema和GraphQL实例
        GraphQLSchema graphQLSchema = buildSchema(sdl);
        this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
    }

    @Autowired
    GraphQLDataFetchers graphQLDataFetchers;

	//抓取数据
    private GraphQLSchema buildSchema(String sdl) {
        TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
        RuntimeWiring runtimeWiring = buildWiring();
        SchemaGenerator schemaGenerator = new SchemaGenerator();
        return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
    }
    
	/*buildWiring使用graphQLDataFetchers bean实际注册两个DataFetchers:
	一个用于检索具有特定ID的图书
	一个用于获取特定书籍的作者*/
	
    private RuntimeWiring buildWiring() {
        return RuntimeWiring.newRuntimeWiring()
                .type(newTypeWiring("Query")
                        .dataFetcher("bookById", graphQLDataFetchers.getBookByIdDataFetcher()))
                .type(newTypeWiring("Book")
                        .dataFetcher("author", graphQLDataFetchers.getAuthorDataFetcher()))
                .build();
    }
}

Interfaz importante (no cree la suya propia):
DataFetcher es una interfaz con un solo método, solo acepta un único parámetro de tipo DataFetcherEnvironment;
cuando GraphQL Java ejecuta una consulta, llamará al apropiado para cada campo encontrado en la consulta Dispositivo de tabla de datos.

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

Supongamos que hay un mapeo de libros no coincidente que tiene una clave totalPages en lugar de pageCount. Esto dará como resultado un valor pageCount vacío para cada libro, porque PropertyDataFetcher no puede obtener el valor correcto. Para resolver este problema, debe registrar un nuevo DataFetcher para Book (no es necesario en este caso)

 // 在 GraphQLDataFetchers class
    // 实现 DataFetcher
    public DataFetcher getPageCountDataFetcher() {
        return dataFetchingEnvironment -> {
            Map<String,String> book = dataFetchingEnvironment.getSource();
            return book.get("totalPages");
        };
    }

Cree una nueva clase GraphQLDataFetchers, que contiene una lista de ejemplos de libros y autores

@Component
public class GraphQLDataFetchers {

    private static List<Map<String, String>> 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")
    );

    private static List<Map<String, String>> 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")
    );

    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);
        };
    }
}

Agregue el método principal de aplicación para iniciar la prueba del proyecto

package com.graphqljava.tutorial.bookdetails;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BookDetailsApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookDetailsApplication.class, args);
    }

}

Los resultados se pueden obtener
Inserte la descripción de la imagen aquí
claramente a través de la prueba de la versión web https://cpq-dev.ext.hp.com/playground
(la zona de juegos puede instalar el software de prueba correspondiente, como cartero, altair, este artículo utiliza la versión web, si la hubiera Si tiene preguntas, consulte el código fuente: https://github.com/graphql-java/tutorials)

3.2 Golang + graphql

① Instale el soporte correspondiente

go get github.com/graphql-go/graphql

(Este directorio está debajo del directorio de ruta. El blog anterior tuvo problemas con el paquete del tutorial. Puede explorarlo. Si no conoce el directorio de ruta de su proyecto, puede usar el comando go Current GOPATH para encontrarlo)

② Ejemplo de aplicación
El siguiente es un ejemplo simple, que define un patrón con un campo de tipo de cadena de saludo y un método Resolve que devuelve el mundo de cadenas. Ejecute la consulta GraphQL en este modo e imprima la salida del resultado en formato JSON

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/graphql-go/graphql"
)

func main() {
	// Schema
	fields := graphql.Fields{
		"hello": &graphql.Field{
			Type: graphql.String,
			Resolve: func(p graphql.ResolveParams) (interface{}, error) {
				return "world", nil
			},
		},
	}
	rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
	schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
	schema, err := graphql.NewSchema(schemaConfig)
	if err != nil {
		log.Fatalf("failed to create new schema, error: %v", err)
	}

	// Query
	query := `
		{
			hello
		}
	`
	params := graphql.Params{Schema: schema, RequestString: query}
	r := graphql.Do(params)
	if len(r.Errors) > 0 {
		log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
	}
	rJSON, _ := json.Marshal(r)
	fmt.Printf("%s \n", rJSON) // {"data":{"hello":"world"}}
}

El anterior es un ejemplo simple. Para obtener recomendaciones de casos más interesantes y complejos, vaya a
https://github.com/graphql-go/graphql/tree/master/examples/
https://github.com/graphql-go/graphql/blob/master /graphql_test.go aprender

También tengo un estudio preliminar de graphql, y espero que los grandes puedan dar más sugerencias.

Este artículo se refiere a aprender del
sitio web oficial https://graphql.org/ y el código fuente de git relacionado

Recomendación personal https://blog.csdn.net/qq_41882147/article/details/82966783, muy detallada, la introducción también es más práctica, adecuada para el aprendizaje avanzado

Supongo que te gusta

Origin blog.csdn.net/MatChen/article/details/111516086
Recomendado
Clasificación