1.5使用GraphQL组合API 原创

鸿蒙开发之南拳北腿
发布于 2023-8-7 21:50
浏览
0收藏

       传统Rest API是由后端决定请求接口时输出的数据结构。GraphQL是一种用于API的查询语言,使得客户端能根据自己的需要获取数据,没有任何冗余,从而减少不必要的网络传输浪费。本节介绍使用Quarkus来实现GraphQL基本功能。

1.5.1 添加GraphQL功能扩展

       在pom.xml文件中添加smallrye-graphql扩展来启用GraphQL支持:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-graphql</artifactId>
</dependency>


1.5.2 创建领域类

创建两个领域类Book(书籍)和Catalog(目录),代码如下:

package manon.wang.domain;

import java.util.List;

/**
* 书籍
*/
public class Book {
    public String bookName;// 书名
    public String language;//语言
    public String author;//作者
    public List<Catalog> catalogs;// 目录
}


package manon.wang.domain;

import java.util.List;

/**
目录
 */
public class Catalog {
    public Integer id;// ID
    public String chapter;// 章节
    public List<String> content;//内容
}


1.5.3 创建服务层代码

创建一个书籍服务类BookService。本专栏第5章讲解通过数据库增、删、改、查数据的方法,本节为方便演示,使用在构造函数中初始化演示数据的方式。同时,实现三个方法,分别是获得所有书籍、根据书名查询书籍和新增书籍,代码如下:

package manon.wang.service;

import manon.wang.domain.Book;
import manon.wang.domain.Catalog;

import javax.enterprise.context.ApplicationScoped;
import java.util.ArrayList;
import java.util.List;

/**
* 书籍服务层
*/
@ApplicationScoped
public class BookService {

    private List<Book> books = new ArrayList<>();

    /**
    * 构造函数
    */
    public BookService() {
        /**
        * 第一本书
        */
        Book book = new Book();
        book.bookName = "拥抱云原生——Quarkus快速开发指南";
        book.language = "Quarkus";
        book.author = "李程华";

        List<Catalog> catalogs = new ArrayList<>();

        Catalog catalog = new Catalog();
        catalog.id = 1;
        catalog.chapter = "第1章 Hello Quarkus";
        List<String> content = new ArrayList<>();
        content.add("1.1 云原生时代的宠儿Quarkus");
        content.add("1.2 搭建开发环境");
        content.add("1.3 Hello Quarkus");
        content.add("1.4 生成OpenAPI规范文档");
        content.add("1.5 使用GraphQL组合API");
        content.add("1.6 应用打包方式");
        content.add("1.7 总结与回顾");
        catalog.content = content;
        catalogs.add(catalog);

        catalog = new Catalog();
        catalog.id = 2;
        catalog.chapter = "第2章 从SpringCloud到Quarkus";
        content = new ArrayList<>();
        content.add("2.1 Quarkus微服务生命周期");
        content.add("2.2 开发REST API");
        content.add("2.3 Quarkus的依赖注入");
        content.add("2.4 Quarkus的微服务配置");
        content.add("2.5 常用数据校验注解");
        content.add("2.6 异常与日志处理");
        content.add("2.7 总结与回顾");
        catalog.content = content;
        catalogs.add(catalog);

        book.catalogs = catalogs;

        books.add(book);

        /**
        * 第二本书
        */
        book = new Book();
        book.bookName = "HarmonyOS 3.0 ArkUI eTS 开发实战";
        book.language = "鸿蒙eTS";
        book.author = "李程华";

        catalogs = new ArrayList<>();

        catalog = new Catalog();
        catalog.id = 1;
        catalog.chapter = "第1章 鸿蒙3.0真的来了";
        content = new ArrayList<>();
        content.add("1.1 鸿蒙3.0 App开发技术选型");
        content.add("1.2 DevEco Studio 3.0 Beta2 for HarmonyOS下载与安装");
        content.add("1.3 完成开发者认证");
        content.add("1.4 调试代码、本地预览和远程模拟器");
        content.add("1.5 真机调试与应用发布");
        content.add("1.6 总结与回顾");
        catalog.content = content;
        catalogs.add(catalog);

        catalog = new Catalog();
        catalog.id = 2;
        catalog.chapter = "第2章 揭开方舟开发框架ArkUI(eTS)的神秘面纱";
        content = new ArrayList<>();
        content.add("2.1 eTS物种起源");
        content.add("2.2 基于eTS的ArkUI有什么优势");
        content.add("2.3 ArkUI App设计规范");
        content.add("2.4 实现沉浸式体验的状态栏");
        content.add("2.5 全场景开发的优点和痛点");
        content.add("2.6 ArkUI实现一次开发多端部署");
        content.add("2.7 总结与回顾");
        catalog.content = content;
        catalogs.add(catalog);

        book.catalogs = catalogs;

        books.add(book);
    }

    /**
    * 获得所有书籍
    * @return
    */
    public List<Book> getAllBooks() {
    		return books;
    }

    /**
    * 根据书名查询书籍
    * @param bookName
    * @return
    */
    public Book getBook(String bookName) {
        for (Book book:
          	books) {
            if(bookName.equals(book.bookName)){
              	return book;
            }
        }
        return null;
    }

    /**
    * 新增书籍
    * @param book
    */
    public void addBook(Book book) {
    		books.add(book);
    }
}


1.5.4 创建资源类

创建一个资源类GraphQLResource.java,在类上面加上“@GraphQLApi”注解。代码如下:

提示下一章讲解@ApplicationScoped和@Inject注解,这里可以不用关注。


package manon.wang;

import org.eclipse.microprofile.graphql.*;
import manon.wang.domain.Book;
import manon.wang.service.BookService;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.List;

@ApplicationScoped
@GraphQLApi
public class GraphQLResource {

    @Inject
    BookService bookService;

    @Query("allBooks")// 查询路径,类似于REST的GET方法
    @Description("查询所有书籍")
    public List<Book> getAllBooks() {
        return bookService.getAllBooks();
    }

    @Query
    @Description("根据书名查询书籍")
    public Book getBook(@Name("bookName") String bookName) {
        return bookService.getBook(bookName);
    }

    @Mutation
    public Book createBook(Book book) {
        bookService.addBook(book);
        return book;
    }

}


1.5.5 体验GraphQL查询

运行项目,可以访问3个不同的GraphQL服务,如表所示:

表1-1三种GraphQL服务

路径

作用

/q/graphql-ui

GraphQL开发界面

/graphql/schema.graphql

获取GraphQL模式

/graphql

GraphQL的API终端

首先,我们可以通过/graphql/schema.graphql获取GraphQL模式,看一下GraphQL API的相关接口及数据结构,如图1-22 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-22 获取GraphQL模式


然后,访问路径/q/graphql-ui,在GraphQL开发界面中请求数据,如图1-23 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-23 在GraphQL开发界面请求数据


改变一下请求的数据模型,发现返回的数据结构也做了相应的剪裁,如图1-24 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-24 改变请求的数据模型


根据书名查询某本书籍的示例如图1-25 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-25 根据书名查询某本书籍


在GraphQL中也可以通过“@Mutation”注解构建新增、修改和删除的方法。这里示范一个新增书籍的例子,如图1-26 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-26 新增书籍


再次查询书籍列表,发现列表也已更新。如图1-27 所示:

1.5使用GraphQL组合API-鸿蒙开发者社区

图1-27 新增书籍


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2023-8-7 21:53:09修改
收藏
回复
举报
回复
    相关推荐