当前位置:   article > 正文

Spring Boot集成Graphql快速入门Demo

Spring Boot集成Graphql快速入门Demo

1.Graphql介绍

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

优势

  1. GraphQL 速度快,并且比较稳定,GraphQL 的操作是在数据层面的,所以比较快。

  2. GraphQL 可以获取更多的资源,当查询一个数据的时候,不止是这个数据,甚至可以很快地查询到数据引用的另一个数据。GraphQL 可以在单个请求中去获取尽量多的数据,并且在弱网状态下,GraphQL 依旧表现出色。

  3. GraphQL 是单端点查询,并在此端点中去完成所有的查询。

  4. GraphQL 的可持续性非常出色,无论是新字段、还是旧字段,它都能很好地去处理,可维护性也极佳。

  5. GraphQL 具有向下兼容的特性,就算是很久很久以前的功能,GraphQL 还是能很好地去兼容它,保证旧版本的正常运行,同时又不影响新功能的加入以及整体的稳定性。这样做的好处就是,不需要去担忧版本号问题了。

  6. GraphQL 具有强类型,在 GraphQL 的查询中,一个级别对应一个强类型,这个类型充当一个字段的描述。这样的好处就是,在查询之前,可以校验出错误并提示,方便定位问题,提高性能。

  7. 自省:可以查询 GraphQL 服务器支持的类型。这为工具和客户端软件创建了一个强大的平台,可以在这些信息的基础上构建静态类型语言的代码生成、我们的应用程序框架、Relay 或 GraphiQL 等 IDE。

  8. GraphQL 支持使用者去决定服务器支持的类型。这样的好处就是,给很多使用 GraphQL 的 工具或者端建立了一个比较成熟且强大的应用平台,通过这个平台,一些框架、工具得到不断地优化提升。

劣势

  1. GraphQL 无法完成深度查询,所以无法对于未知深度的数据进行一次性查询。

  2. GraphQL 具有非常死板的响应结构,你必须遵从这个结构去查询数据,或者自己添加一个转换器来转换。

  3. GraphQL 无法进行网络级别的缓存,你必须使用另外别的办法进行持久查询。

  4. GraphQL 默认没有上传文件的功能,GraphQL 也不接收文件类型的参数,但是你可以使用 REST 的方式进行上传文件,达到上传文件的目的。

  5. GraphQL 的执行是不可预测的,因为 GraphQL 太过于灵活了。

  6. 同样的一个简单的 API,GraphQL 会表现得很复杂,所以建议简单 API 使用 RSET。

2.mysql环境搭建

参考代码仓库里面的mysql模块,这里只贴出docker-compose.yml

  1. version: '3'
  2. services:
  3. mysql:
  4. image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7
  5. container_name: mysql_3306
  6. restart: unless-stopped
  7. volumes:
  8. - "./mysql/my.cnf:/etc/mysql/my.cnf"
  9. - "./mysql/init-file.sql:/etc/mysql/init-file.sql"
  10. - "./mysql/data:/var/lib/mysql"
  11. # - "./mysql/conf.d:/etc/mysql/conf.d"
  12. - "./mysql/log/mysql/error.log:/var/log/mysql/error.log"
  13. - "./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d" # init sql script directory -- tips: it can be excute when `/var/lib/mysql` is empty
  14. environment: # set environment,equals docker run -e
  15. TZ: Asia/Shanghai
  16. LANG: en_US.UTF-8
  17. MYSQL_ROOT_PASSWORD: root # set root password
  18. MYSQL_DATABASE: demo # init database name
  19. ports: # port mappping
  20. - "3306:3306"

运行

docker-compose -f docker-compose.yml -p mysql5.7 up -d

初始化脚本

  1. CREATE DATABASE IF NOT EXISTS `BOOK_API_DATA`;
  2. USE `BOOK_API_DATA`;
  3. CREATE TABLE IF NOT EXISTS `Book` (
  4. `id` int(20) NOT NULL AUTO_INCREMENT,
  5. `name` varchar(255) DEFAULT NULL,
  6. `pageCount` varchar(255) DEFAULT NULL,
  7. PRIMARY KEY (`id`),
  8. UNIQUE KEY `Index_name` (`name`)
  9. ) ENGINE=InnoDB AUTO_INCREMENT=235 DEFAULT CHARSET=utf8;
  10. CREATE TABLE `Author` (
  11. `id` INT(20) NOT NULL AUTO_INCREMENT,
  12. `firstName` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
  13. `lastName` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
  14. `bookId` INT(20) NULL DEFAULT NULL,
  15. PRIMARY KEY (`id`) USING BTREE,
  16. UNIQUE INDEX `Index_name` (`firstName`) USING BTREE,
  17. INDEX `FK_Author_Book` (`bookId`) USING BTREE,
  18. CONSTRAINT `FK_Author_Book` FOREIGN KEY (`bookId`) REFERENCES `BOOK_API_DATA`.`Book` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
  19. )
  20. COLLATE='utf8_general_ci'
  21. ENGINE=InnoDB
  22. AUTO_INCREMENT=6
  23. ;
  24. INSERT INTO `Book` (`id`, `name`, `pageCount`) VALUES (1, 'the golden ticket', '255');
  25. INSERT INTO `Book` (`id`, `name`, `pageCount`) VALUES (2, 'coding game', '300');
  26. INSERT INTO `Author` (`id`, `firstName`, `LastName`, `bookId`) VALUES (4, 'Brendon', 'Bouchard', 1);
  27. INSERT INTO `Author` (`id`, `firstName`, `LastName`, `bookId`) VALUES (5, 'John', 'Doe', 2);

3.代码工程

 实验目标

实现一个基于graphql查询的例子

实现过程

1. 定义Schema,Schema使用GraphQL Schema Definition Language (SDL)来定义

2. 实现Resolver,Resolver函数负责从数据源中获取请求的数据

3. 配置和启动GraphQL服务器 ,要启动GraphQL服务器,你需要安装相应的依赖和配置服务器

pomxml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>springboot-demo</artifactId>
  7. <groupId>com.et</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>GraphQL</artifactId>
  12. <properties>
  13. <maven.compiler.source>8</maven.compiler.source>
  14. <maven.compiler.target>8</maven.compiler.target>
  15. <kotlin.version>1.5.0</kotlin.version>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-web</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>com.graphql-java-kickstart</groupId>
  24. <artifactId>graphql-spring-boot-starter</artifactId>
  25. <version>12.0.0</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-data-jpa</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>mysql</groupId>
  33. <artifactId>mysql-connector-java</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>com.graphql-java-kickstart</groupId>
  37. <artifactId>graphql-java-tools</artifactId>
  38. <version>12.0.0</version>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-test</artifactId>
  43. <scope>test</scope>
  44. <exclusions>
  45. <exclusion>
  46. <groupId>org.junit.vintage</groupId>
  47. <artifactId>junit-vintage-engine</artifactId>
  48. </exclusion>
  49. </exclusions>
  50. </dependency>
  51. <dependency>
  52. <groupId>com.google.guava</groupId>
  53. <artifactId>guava</artifactId>
  54. <version>26.0-jre</version>
  55. </dependency>
  56. <dependency>
  57. <groupId>org.apache.tomcat.embed</groupId>
  58. <artifactId>tomcat-embed-jasper</artifactId>
  59. <scope>provided</scope>
  60. </dependency>
  61. </dependencies>
  62. </project>

GraphQLQueryResolver

  1. package com.et.graphql.queryresolvers;
  2. import com.et.graphql.model.Author;
  3. import com.et.graphql.model.Book;
  4. import com.et.graphql.repository.AuthorRepository;
  5. import com.et.graphql.repository.BookRepository;
  6. import graphql.kickstart.tools.GraphQLQueryResolver;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Component;
  9. @Component
  10. public class BookQuery implements GraphQLQueryResolver{
  11. @Autowired
  12. BookRepository bookRepository;
  13. @Autowired
  14. AuthorRepository authorRepository;
  15. public Iterable<Book> allBook(){
  16. return bookRepository.findAll();
  17. }
  18. public Book getBookByName(String name){
  19. return bookRepository.findBookByName(name);
  20. }
  21. public Iterable<Author> allAuthor(){
  22. return authorRepository.findAll();
  23. }
  24. }
  1. package com.et.graphql.queryresolvers;
  2. import com.et.graphql.model.Book;
  3. import com.et.graphql.repository.BookRepository;
  4. import graphql.kickstart.tools.GraphQLMutationResolver;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Component;
  7. import java.util.Optional;
  8. @Component
  9. public class BookMutation implements GraphQLMutationResolver {
  10. @Autowired
  11. BookRepository bookRepository;
  12. public Book newBook(String name, String pageCount){
  13. Book book = new Book();
  14. book.setName(name);
  15. book.setPageCount(pageCount);
  16. return bookRepository.save(book);
  17. }
  18. public Book deleteBook(Integer id){
  19. Book deleteBook = new Book();
  20. Optional<Book> findBook = bookRepository.findById(id);
  21. if(findBook.isPresent()){
  22. bookRepository.delete(findBook.get());
  23. deleteBook = findBook.get();
  24. }
  25. return deleteBook;
  26. }
  27. }
  1. package com.et.graphql.queryresolvers;
  2. import com.et.graphql.model.Author;
  3. import com.et.graphql.model.Book;
  4. import com.et.graphql.repository.AuthorRepository;
  5. import graphql.kickstart.tools.GraphQLResolver;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Component;
  8. @Component
  9. public class BookAuthorResolver implements GraphQLResolver<Book> {
  10. @Autowired
  11. AuthorRepository authorRepository;
  12. public Author getAuthor(Book book){
  13. return authorRepository.findAuthorByBookId(book.getId());
  14. }
  15. }

graphqls(/resources/graphql)

  1. type Book {
  2. id: Int
  3. name: String
  4. pageCount: String
  5. author: Author
  6. }
  7. type Query {
  8. allBook: [Book]
  9. allAuthor:[Author]
  10. getBookByName(name: String): Book
  11. }
  12. type Mutation {
  13. newBook(name: String!, pageCount: String): Book
  14. deleteBook(id:Int!):Book
  15. }
  16. type Author {
  17. id: Int
  18. firstName: String
  19. lastName: String
  20. bookId: Int
  21. }

model

  1. package com.et.graphql.model;
  2. import javax.persistence.*;
  3. @Entity
  4. @Table(name = "Author", schema = "BOOK_API_DATA")
  5. public class Author {
  6. @Id
  7. @GeneratedValue(strategy = GenerationType.AUTO)
  8. Integer id;
  9. @Column(name = "firstname")
  10. String firstName;
  11. @Column(name = "lastname")
  12. String lastName;
  13. @Column(name = "bookid")
  14. Integer bookId;
  15. public Author(Integer id, String firstName, String lastName, Integer bookId) {
  16. this.id = id;
  17. this.firstName = firstName;
  18. this.lastName = lastName;
  19. this.bookId = bookId;
  20. }
  21. public Author() {
  22. }
  23. public Integer getId() {
  24. return id;
  25. }
  26. public String getFirstName() {
  27. return firstName;
  28. }
  29. public String getLastName() {
  30. return lastName;
  31. }
  32. public void setId(Integer id) {
  33. this.id = id;
  34. }
  35. public void setFirstName(String firstName) {
  36. this.firstName = firstName;
  37. }
  38. public void setLastName(String lastName) {
  39. this.lastName = lastName;
  40. }
  41. public Integer getBookId() {
  42. return bookId;
  43. }
  44. public void setBookId(Integer bookId) {
  45. this.bookId = bookId;
  46. }
  47. }
  1. package com.et.graphql.model;
  2. import javax.persistence.*;
  3. @Entity
  4. @Table(name = "Book", schema = "BOOK_API_DATA")
  5. public class Book {
  6. @Id
  7. @GeneratedValue(strategy = GenerationType.AUTO)
  8. private Integer id;
  9. private String name;
  10. @Column(name = "pagecount")
  11. private String pageCount;
  12. public Book(Integer id, String name, String pageCount) {
  13. this.id = id;
  14. this.name = name;
  15. this.pageCount = pageCount;
  16. }
  17. public Book() {
  18. }
  19. public Integer getId() {
  20. return id;
  21. }
  22. public void setId(Integer id) {
  23. this.id = id;
  24. }
  25. public String getName() {
  26. return name;
  27. }
  28. public void setName(String name) {
  29. this.name = name;
  30. }
  31. public String getPageCount() {
  32. return pageCount;
  33. }
  34. public void setPageCount(String pageCount) {
  35. this.pageCount = pageCount;
  36. }
  37. }

repository

  1. package com.et.graphql.repository;
  2. import com.et.graphql.model.Author;
  3. import org.springframework.data.repository.CrudRepository;
  4. public interface AuthorRepository extends CrudRepository<Author, Integer> {
  5. Author findAuthorByBookId(Integer bookId);
  6. }
  1. package com.et.graphql.repository;
  2. import com.et.graphql.model.Book;
  3. import org.springframework.data.repository.CrudRepository;
  4. public interface BookRepository extends CrudRepository<Book, Integer> {
  5. Book findBookByName(String name);
  6. }

DemoApplication.java

  1. package com.et.graphql;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.context.annotation.ComponentScan;
  5. @SpringBootApplication
  6. @ComponentScan(basePackages = "com.et.graphql.queryresolvers")
  7. public class BookAPIApplication {
  8. public static void main(String[] args) {
  9. SpringApplication.run(BookAPIApplication.class, args);
  10. }
  11. }

application.yaml

  1. spring.jpa.hibernate.ddl-auto=none
  2. spring.jpa.database=mysql
  3. spring.jpa.open-in-view=true
  4. spring.jpa.show-sql=true
  5. server.port=8088
  6. #logging.level.org.hibernate=DEBUG
  7. logging.level.org.hibernate.SQL=DEBUG
  8. spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
  9. spring.jpa.hibernate.use-new-id-generator-mappings= false
  10. # book api db"
  11. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
  12. spring.datasource.username=root
  13. spring.datasource.password=root

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo

4.测试

启动spring boot应用 打开postman,调用

http://127.0.0.1:8088/graphql 输入

  1. query {
  2. allBook{
  3. id
  4. name
  5. pageCount
  6. }
  7. }

返回结果4e17233ae985cef2ace7a76ad62597a6.png

5.引用

  • https://www.cnblogs.com/zcqiand/p/18011513

  • http://www.liuhaihua.cn/archives/710416.html

  • https://graphql.org/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/416261
推荐阅读
相关标签
  

闽ICP备14008679号