• 使用Spring Boot实现GraphQL


    项目准备

    开发环境

    • Windows10
    • Java 11(采用OpenJDK jdk11.0.4+11 OpenJ9 0.15.1)
    • Maven 3.5.4
    • STS 4.4.0

    创建一个基本Spring Boot项目

    • Spring Boot 2.1.9

    添加GraphQL Java依赖项

    使用 graphql-java-kickstart / graphql-spring-boot 。要执行的最小依赖项仅如下所示。

    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
        <version>5.10.0</version>
    </dependency>

    还需要将kotlin的版本指定为属性(如果没有描述,则在运行时会发生异常)。

    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.3.10</kotlin.version>
    </properties>

    API第1部分:支持简单的get查询

    考虑为以下模型获取ID的一个实体。

    Member ( member ID , name, age)

    GraphQL定义创建

    src/main/resources/graphql 创建一个描述类型定义和查询定义的文件,如下所示。

    type Member {
        memberId: ID!
        name: String!
        age: Int
    }
    
    type Query {
        getMember(memberId:ID!): Member
    }

    Java端实现

    实体类

    首先,创建一个与类型定义匹配的实体类。

    @Data
    public class Member {
        private String memberId;
        private String name;
        private Integer age;
    }

    查询

    接下来,创建与查询对应的方法。 GraphQLQueryResolver 创建一个实现类,并创建一个与查询名称同名的方法。定义一个也与参数和返回值相对应的类,并实现实际返回的实例。创建返回值的方法是任意的(使用MyBatis映射器(省略))。用所有值填写返回值字段​​可以作为Servlet返回。

    @Component
    public class MemberQueryResolver implements GraphQLQueryResolver {
    
        @Autowired
        MemberMapper mapper;
    
        public Member getMember(String memberId) {
            return mapper.getById(memberId);
        }
    }

    执行

    启动配置

    在 application.yml 中描述Servlet的启动配置。

    graphql:
      servlet:
        enabled: true
        mapping: /graphql
        corsEnabled: true

    启动

    写入后,将创建的项目作为Spring Boot App执行。

    查询发布

    http://localhost:8080/graphqlIf queryyou设置GraphQL查询作为URL参数的值并访问它,将获得结果。

    例如,在发出以下查询时

    query {
      getMember(memberId:"aaaaaaaa") {
        name
      }
    }

    除了新行和不必要的空白编码,然后查询 %7BgetMember(memberId:%22aaaaaaaa%22)%7Bname%7D%7Dto 以签入,因为curl。

    $ curl -s "http://localhost:8080/graphql?query=query%7BgetMember(memberId:%22aaaaaaaa%22)%7Bname%7D%7D"
    {"data":{"getMember":{"name":"齊藤京子"}}}

    如果更改 memberId 并将年龄添加到采集密钥中,将得到以下结果。

    $ curl -s "http://localhost:8080/graphql?query=query%7BgetMember(memberId:%22bbbbbbbb%22)%7Bname,age%7D%7D"
    {"data":{"getMember":{"name":"佐々木久美","age":23}}}

    引入Graph i QL

    encodeuris由于使用curl或浏览器访问每个查询太麻烦,我们将引入一个工具来尝试查询。这次我们将使用图i QL。

    添加依赖项

    graph“i”将 ql-spring-boot-starter 程序添加到依赖项中。

    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphiql-spring-boot-starter</artifactId>
        <version>5.10.0</version>
    </dependency>

    execution

    启动配置

    在 application.yml 中描述Servlet的启动配置。目前,如果您有以下设置,请启动它。

    graphiql:
      enabled: true
      mapping: /graphiql
      endpoint:
        graphql: /graphql

    启动

    写入后,将创建的项目作为Spring Boot App执行。通道

    当服务器启动时从浏览器启动 http://localhost:8080/graphiql .

    在左侧的查询创建屏幕上,字段名有一个输入帮助,执行结果的json也以格式化的形式显示。

    API#2:尝试嵌套类型

    除了第1部分中的模型之外,还可以考虑通过关系来获取一个实体的模型,该模型通过关系将以下多对多模型连接起来。

    Member ( member ID , name, age)
    
    Music ( song ID , song name)
    
    Participating song relation ( song ID , member ID )

    GraphQL定义修改

    添加到定义文件中。由于它是多对多成员,因此它可以同时使用 Musicis Musican Memberarray 。

    type Member {
        memberId: ID!
        name: String!
        age: Int
        joining: [Music]
    }
    
    type Music {
        musicId: ID!
        title: String!
        members: [Member]
    }
    
    type Query {
        getMember(memberId:ID!): Member
        getMusic(musicId:ID!):Music
    }

    Java端实现

    实体类

    创建与新类型定义相对应的实体类。将属性定义为数组列表。

    @Data
    public class Music {
        private String musicId;
        private String title;
        private List<Member> members;
    }

    members现在已添加属性,请添加一个字段。

    @Data
    public class Member {
        private String memberId;
        private String name;
        private int age;
        private List<Music> joining;
    }

    查询

    MemberQueryResolverIs 保持不变。 Member.joining 创建在另一个类中插入值的逻辑。

    在 DataClass(<>inside) 中, GraphQlResolver 创建一个指定插入目标实体类的实现类,并创建一个与插入目标字段同名的方法。在参数中指定插入目标的实体类,并返回要插入的实例。

    ( MusicMapper.getMusicsOfMember 是一种通过关系获取与 memberId 关联的所有音乐的方法(省略实现内容)

    @Component
    public class MemberResolver implements GraphQLResolver<Member> {
    
        @Autowired
        MusicMapper mapper;
    
        public List<Music> joining(Member member) {
            return mapper.getMusicsOfMember(member.getMemberId());
        }
    }

    execution

    当您发出以下查询时

    query {
      getMember(memberId:"cccccccc") {
        name, age, joining {
          title
        }
      }
    }

    将会返回下面的数据:

    {
      "data": {
        "getMember": {
          "name": "富田鈴花",
          "age": 18,
          "joining": [
            {
              "title": "こんなに好きになっちゃっていいの?"
            },
            {
              "title": "ホントの時間"
            },
            {
              "title": "まさか 偶然…"
            },
            {
              "title": "川は流れる"
            }
          ]
        }
      }
    }

    在STS的调试模式下进行检查时,您可以看到搜索结果插入到字段中而非的实例作为 MemberResolver.joining 传递参数 joining 。

    此外,joining如果未在查询中指定,或者如果指定的 memberId 不存在且结果为 null ,则不会执行此方法。

    API#3:尝试创建注册函数

    到目前为止,我们只处理了查询(对应于CRUD中的R)。接下来,尝试实现变异(对应于CRUD C/U/D)。

    添加了GraphQL定义

    添加到定义文件中。

    type Mutation {
        registerMusic(title: String!): Music
    }

    Java端实现

    因为这里创建的是一个与现有实体相对应的实体。 GraphQlmutationResolver 创建一个实现类,并创建一个带有参数和返回值的方法​​与GraphQL类似的查询。

    ( GenerateId() 是一个生成成为ID的字符串的方法, MusicMapper.insert 是一个插入所有参数信息的方法。(省略实现内容))

    @Component
    public class MusicMutationResolver implements GraphQLMutationResolver {
    
        @Autowired
        MusicMapper mapper;
    
        public Music registerMusic(String title) {
            Music music = new Music();
            music.setMusicId(generateId());
            music.setTitle(title);
            mapper.insert(music);
            return music;
        }
    }

    查询发布

    如果发生突变,则使用后调用API。查询作为JSON格式参数附加。

    *“在查询中转义

    $ curl -s "http://localhost:8080/graphql" -X POST -H "Content-Type: application/json" -d '{"query":"mutation{registerMusic(title:\"NO WAR in the future\"){musicId,title}}"}'
    {"data":{"registerMusic":{"musicId":"hogehoge","title":"NO WAR in the future"}}}

    Graph i QL

    在尝试使用Graph i QL时,在左侧 mutation{…} ,并在其中写入API名称、参数和输出内容,就像在查询中一样。

  • 相关阅读:
    已分区的硬盘如何重新合并, 分出去的盘怎么重新合并
    Shopee个人能入驻开店吗?Shopee一个站点可以开几个店铺?
    Hudi 数据湖的插入,更新,查询,分析操作示例
    Metabase学习教程:入门-2
    【EI检索】第四届公共卫生与数据科学国际学术研讨会(ICPHDS 2023)
    【大数据之Kafka】九、Kafka Broker之文件存储及高效读写数据
    2.6文件服务器
    【100天精通Python】Day63:Python可视化_Matplotlib绘制子图,子图网格布局属性设置等示例+代码
    【NSDictionary的概述 Objective-C语言】
    Hadoop和关系型数据库间的数据传输工具——Sqoop
  • 原文地址:https://blog.csdn.net/JavaShark/article/details/125523580