Spring for GraphQL 官方指南手册

在本教程中,你将使用Spring for GraphQL在Java中创建一个GraphQL服务器。学习本教程之前,需要你具备一定的Spring和Java功底。虽然教程中简要的介绍了GraphQL,但本教程的重点是用Java开发GraphQL服务器。

内容来源:

https://spring.io/guides/gs/graphql-server/

https://www.graphql-java.com/tutorials/getting-started-with-spring-boot

GraphQL简介

GraphQL是一个从服务端获取数据的查询语言。它是REST、SOAP或gRPC的替代方案。假设我们想从在线商店后端查询某本书的详细信息。
使用GraphQL,你可以向服务器发送以下查询,以获取id为“book-1”的图书的详细信息:

query bookDetails {
  bookById(id: "book-1") {
    id
    name
    pageCount
    author {
      firstName
      lastName
    }
  }
}

注意这不是JSON(尽管它与JSON特别相似),这个请求的意思是:

  • 对id为“book-1”的图书执行查询;
  • 检索结果需要返回:id、name、pageCount和author;
  • auth返回firstName和lastName。

响应结果是标准的JSON:

{
  "bookById": {
    "id":"book-1",
    "name":"Effective Java",
    "pageCount":416,
    "author": {
      "firstName":"Joshua",
      "lastName":"Bloch"
    }
  }
}

GraphQL的一个非常重要的属性是它是静态类型的:服务器清楚地知道你可以查询到的每一个对象的样子并且任何一个客户端都能"introspect"服务器并请求”schema“。schema 描述了可能的查询以及可以返回的字段。

schame 在这篇教程中指的是“GraphQL Schema”。

上述描述 schma 如下:

type Query {
    bookById(id: ID): Book
}

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

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

本次教程只关注如何通过在Java代码中通过以上schema实现 GrapQL 服务。
这里仅仅触及了GraphQL的表面。更多信息可以在GraphQL官方页面上找到。

GraphQL Java 概览

GraphQL Java 是GraphQL的Java实现版本。GraphQL Java中最重要的就是 GraphQL Java Engine ,它是其他一切的基础。

GraphQL Java Engine 仅仅是执行查询。它不处理任何HTTP或JSON相关的主题。对于这些方面,我们将使用Spring For GraphQL,它负责通过Spring Boot在HTTP上公开我们的API。

创建GraphQL Java服务的主要步骤如下:

  1. 定义GraphQL Schema.
  2. 决定如何获取查询的实际数据。

案例:查询图书详情

使用Spring for GraphQL 创建服务的核心步骤:

  1. 定义一个GraphQL schema;
  2. 实现一个查询数据逻辑。

我们的样例程序只是一个简单的查询指定数据详情的API,他不是一个全面的API。

创建一个Spring项目

使用 spring initializr 初始化项目,选择依赖见下图
https://start.spring.io/
IDEA
生成项目结构

Spring for GraphQL 添加了许多有用的特性,包括加载schema文件、初始化GraphQL Java以及使用控制器注释简化数据获取。

Schema

在Spring for GraphQL项目中 src/main/resources/graphql 目录下新建一个 schema.graphqls 文件,文件内容如下:
image.png

type Query {
    bookById(id: ID): Book
}

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

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

每个 GraphQL schema 都有一个顶级 Query 类型,字段是程序暴露出的查询操作,这里schema定义了一个 名叫bookById,返回指定图书详情的方法。
这个schema 同时定义了一个具有id,name,pageCount和author字段的Book类型和有firstName和lastName字段的Author类型。
这个schema 同时定义了一个Book类型和Author类型,Book类型有id,name,pageCount和author字段,Author类型有firstName和lastName字段。

上面用于描述模式的领域特定语言称为模式定义语言或SDL。有关更多详细信息,请参阅GraphQL文档

数据来源

GraphQL的一个关键优势是数据可以从任何地方获取。数据可以来自数据库,一个外部服务,或者内存。
为了简化本教程,书籍和作者数据将来自它们各自类中的静态列表。

创建Book和Auth数据源

我们在启动类GraphQlServerApplication统计创建Book and Author 类:

package com.example.graphqlserver;

import java.util.Arrays;
import java.util.List;

public class Book {

    private String id;
    private String name;
    private int pageCount;
    private String authorId;

    public Book(String id, String name, int pageCount, String authorId) {
        this.id = id;
        this.name = name;
        this.pageCount = pageCount;
        this.authorId = authorId;
    }

    private static List<Book> books = Arrays.asList(
            new Book("book-1", "Harry Potter and the Philosopher's Stone", 223, "author-1"),
            new Book("book-2", "Moby Dick", 635, "author-2"),
            new Book("book-3", "Interview with the vampire", 371, "author-3")
    );

    public static Book getById(String id) {
        return books.stream().filter(book -> book.getId().equals(id)).findFirst().orElse(null);
    }

    public String getId() {
        return id;
    }

    public String getAuthorId() {
        return authorId;
    }
}
package com.example.graphqlserver;

import java.util.Arrays;
import java.util.List;

public class Author {

    private String id;
    private String firstName;
    private String lastName;

    public Author(String id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    private static List<Author> authors = Arrays.asList(
            new Author("author-1", "Joanne", "Rowling"),
            new Author("author-2", "Herman", "Melville"),
            new Author("author-3", "Anne", "Rice")
    );

    public static Author getById(String id) {
        return authors.stream().filter(author -> author.getId().equals(id)).findFirst().orElse(null);
    }

    public String getId() {
        return id;
    }
}

编写获取数据代码

Spring for GraphQL提供了一种基于注解的编程模型,用于声明处理程序方法,以获取特定GraphQL字段的数据。
创建BookController.java,代码如下:

package com.wheelmouse.graphql.controller;

import com.wheelmouse.graphql.entities.Author;
import com.wheelmouse.graphql.entities.Book;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.graphql.data.method.annotation.SchemaMapping;
import org.springframework.stereotype.Controller;

/**
 * @author wheelmouse
 * @date 2023-12-14 14:46
 */
@Controller
public class BookController {
    @QueryMapping
    public Book bookById(@Argument String id) {
        return Book.getById(id);
    }

    @SchemaMapping
    public Author author(Book book) {
        return Author.getById(book.authorId());
    }
}

@QueryMapping 注解负责将java方法与 schema 中的 type Query 字段绑定,根据方法名寻找Query的字段。同时@QueryMapping 也可以在直接注释上声明时指定对应的Query字段。Spring for GraphQL 使用 RuntimeWiring.Builder 将处理程序方法注册为查询字段bookById的graphql.schema.DataFetcher。

在 GraphQL Java 中,DataFetchingEnvironment 提供了对特定字段参数值映射的访问。使用 @Argument 注解可将参数绑定到目标对象并注入到处理程序方法中。

默认情况下,方法参数名用于查找参数。参数名称可在注解中指定。

@SchemaMapping 注解将处理程序方法映射到 GraphQL schema 中的一个字段,并将其声明为该字段的 DataFetcher。字段名默认为方法名,类型名默认为注入方法的源/父对象的简单类名。在本例中,字段默认为 author,类型默认为 Book。类型和字段可在注解中指定。
有关更多信息,请参阅 Spring for GraphQL 注解控制器功能的文档。
这就是我们需要的所有代码!
让我们运行第一个查询吧。

执行我们的第一个查询

启动GraphiQL Playground

GraphiQL是一个用于编写和执行查询的的可视化界面,在application.properties 增加如下配置开启GraphiQL:

spring.graphql.graphiql.enabled=true
spring.graphql.graphiql.path=/graphiql

启动项目,登录http://localhost:8080/graphiql.
在控制台输入一下内容:

query bookDetails {
  bookById(id: "book-1") {
    id
    name
    pageCount
    author {
      id
      firstName
      lastName
    }
  }
}

image.png
点击执行,响应结果如下:
image.png祝贺你,你已经构建了GraphQL服务并执行了第一个查询!在Spring for GraphQL的帮助下,您只需要几行代码就可以实现这一点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP(面向切面编程)是Spring框架中的一个重要模块用于实现横切关注点的块化。它通过在程序运行间动态地将代码织入到应用程序的特定位置,从而实现对应用程序的增强。 以下是Spring AOP初学者指南的主要内容: 1. 切面(Aspect):切面是一个模块化的单元,它封装了与横切关注点相关的行为。在Spring AOP中,切面可以是一个类,其中包含了一组通知(Advice)和切点(Pointcut)。 2. 通知(Advice):通知定义了在特定切点上执行的操作。在Spring AOP中,有以下几种类型的通知: - 前置通知(Before Advice):在目标方法执行之前执行。 - 后置通知(After Advice):在目标方法执行之后执行,无论是否发生异常。 - 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行。 - 异常通知(After Throwing Advice):在目标方法抛出异常后执行。 - 环绕通知(Around Advice):包围目标方法的通知,在目标方法执行前后都可以执行自定义的操作。 3. 切点(Pointcut):切点定义了在应用程序中哪些位置应该应用通知。它使用表达式来匹配目标方法。 4. 连接点(Join Point):连接点是在应用程序执行过程中能够插入切面的点。在Spring AOP中,连接点通常是方法的执行。 5. 引入(Introduction):引入允许向现有的类添加新的方法和属性。 6. 织入(Weaving):织入是将切面应用到目标对象并创建新的代理对象的过程。织入可以在编译时、类加载时或运行时进行。 7. 配置Spring AOP:要使用Spring AOP,需要在Spring配置文件中进行相应的配置。可以使用XML配置或基于注解的配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值