https://graphql.cn/learn/

梗概

  • graphQL类似数据库查询语言,可以按需获取对应资源
    • 服务端只需要定义自己的资源(schema,结构无关紧要,因为客户端可以自由探索,并“勾选需要的字段”
  • 也是需要服务端的文档
    • 虽然graphQL提供了schema供客户端查看服务端开放的所有接口,但返回的内容非常多,且相对扁平化,没有很强的结构性,难以查找所需的接口
      • 如GitHub的就返回了15万行的json

100s视频了解

【熟肉】100 秒了解 GraphQL_哔哩哔哩_bilibili

官方描述

官方已经描述的非常简洁清楚:GraphQL | A query language for your API

使用教程

API传输载体

HTTP

  • 可以选择使用http来发送graphQL
    • 在body中放入graphQL

客户端

示例

child::

vue中使用apollo访问graphQL接口

  1. 配置 Apollo 客户端: 创建一个 apollo.js 文件来配置 Apollo 客户端:

    // src/apollo.js
    import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client/core';
    import { DefaultApolloClient } from '@vue/apollo-composable';
    import { provide } from 'vue';
     
    const httpLink = createHttpLink({
      uri: 'https://your-graphql-endpoint.com/graphql',
    });
     
    const cache = new InMemoryCache();
     
    const apolloClient = new ApolloClient({
      link: httpLink,
      cache,
    });
     
    export function provideApolloClient(app) {
      app.provide(DefaultApolloClient, apolloClient);
    }
  2. 在 Vue 应用中提供 Apollo 客户端: 在 main.js 中引入并提供 Apollo 客户端:

    // src/main.js
    import { createApp } from 'vue';
    import App from './App.vue';
    import { provideApolloClient } from './apollo';
     
    const app = createApp(App);
    provideApolloClient(app);
    app.mount('#app');
  3. 使用 Apollo 查询数据: 在组件中使用 useQuery 来执行 GraphQL 查询:

    <!-- src/components/HelloWorld.vue -->
    <template>
      <div>
        <h1>GraphQL Query Example</h1>
        <div v-if="loading">Loading...</div>
        <div v-if="error">Error: {{ error.message }}</div>
        <div v-if="data">
          <p>{{ data.hello }}</p>
        </div>
      </div>
    </template>
     
    <script>
    import { useQuery } from '@vue/apollo-composable';
    import gql from 'graphql-tag';
     
    const HELLO_QUERY = gql`
      query Hello($name: String!) {
        hello(name: $name)
      }
    `;
     
    export default {
      setup() {
        const { result: data, loading, error } = useQuery(HELLO_QUERY, { name: 'World' });
     
        return { data, loading, error };
      },
    };
    </script>
指向原始笔记的链接

graphQL语句

child::

graphQL语句

图解

|

操作

  • 一个基本单位
  • 一个操作有多种类型:查、增改、subscription
    • 这是用来显性告诉服务器这个操作的目的
    • 实际上的增删改查还得取决于服务器怎么解析这个请求
  • 一个操对应一个大括号,大括号里面填写请求内容

操作名

  • 放在操作的大括号前面
  • 可以忽略,即匿名操作

示例

增删改查

child::graphQL增删改查

指向原始笔记的链接

接口内容探索

child::

接口内容探索

梗概

示例

查看字段:

child::

选择所需字段:

指向原始笔记的链接

注释

  • 请求中可以用#来插入一行注释

字段参数

示例

{
  human(id: "1000") {
    name
    height
  }
}
  • 请求human列表中包含id:“1000”这一个键值对的元素

变量

  • 可以给操作定义一个变量(参数)
    • 在操作中就可以使用这个变量
    • 还可以给这个变量定义一个默认值
  • 变量可以在操作外赋值

示例

别名

  • 可以给某个请求字段起一个别名,让结构返回这个别名,而不是原字段名

片段

  • 可以在请求外定义一个片段,其实就是一些请求的集合
  • 在别的请求中,可以调用这个片段,就相当于在调用的地方写下了片段中的请求

变量

  • 片段可以使用调用方请求的变量

指令

  • 在某些请求字段后,可以追加一个指令
    • 指令可以使用操作中的变量
  • 指令会对字段进行一定的修改
    • 字段 @include()会根据表达式内的真假来判断是否发送该字段请求
      • 即最终结果是否包含该字段

示例

@include(if: Boolean) 指令允许你根据条件包含某个字段。

query getUser($showEmail: Boolean!) {
  user(id: "1") {
    id
    name
    email @include(if: $showEmail)
  }
}

在这个示例中,如果变量 showEmailtrue,则会返回用户的电子邮件;如果为 false,则不会返回电子邮件字段。

缓存

child::

graphQL客户端缓存

方案

  • child::Apollo Client Cache
  • Relay Cache:Relay 是 Facebook 开发的 GraphQL 客户端,也内置了缓存系统。Relay 根据查询的 Fragment 结构来缓存数据,并确保缓存与查询结果保持同步。
指向原始笔记的链接

服务端

服务端定义字段

child::

定义graphQL

示例

NestJs

配置 GraphQL 模块: 在你的主模块(例如 app.module.ts)中导入并配置 GraphQLModule

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { join } from 'path';
@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
    }),
  ],
})
export class AppModule {}

定义 GraphQL 类型: 创建用户(User)和帖子(Post)类型,并定义它们之间的关系。 TypeScript

import { ObjectType, Field, Int, ID } from '@nestjs/graphql';
@ObjectType()
export class User {
  @Field(type => ID)
  id: number;
  @Field()
  name: string;
  @Field(type => [Post])
  posts: Post[];
}
@ObjectType()
export class Post {
  @Field(type => ID)
  id: number;
  @Field()
  title: string;
  @Field()
  content: string;
  @Field(type => User)
  author: User;
}

创建 Resolver: 创建用户和帖子解析器,处理查询和变更。

import { Resolver, Query, Mutation, Args, ResolveField, Parent } from '@nestjs/graphql';
import { User } from './user.model';
import { Post } from './post.model';
 
@Resolver(of => User)
export class UserResolver {
  @Query(returns => [User])
  users(): User[] {
    // 返回用户列表
  }
 
  @ResolveField(returns => [Post])
  posts(@Parent() user: User): Post[] {
    // 根据父字段user的请求相应值返回用户的帖子列表
  }
}
 
@Resolver(of => Post)
export class PostResolver {
  @Query(returns => [Post])
  posts(): Post[] {
    // 返回帖子列表
  }
 
  @Mutation(returns => Post)
  createPost(@Args('title') title: string, @Args('content') content: string, @Args('authorId') authorId: number): Post {
    // 创建并返回新帖子
  }
 
  @ResolveField(returns => User)
  author(@Parent() post: Post): User {
    // 根据父字段的值来返回帖子的作者
  }
}
指向原始笔记的链接

开启graphQL playground

child::

graphQL playground

梗概

  • 相当于一个graphQL接口的交互式文档

开启playground

示例(NestJs

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: true,
    }),
  ],
})

使用

child::

接口内容探索

梗概

示例

查看字段:

child::

选择所需字段:

指向原始笔记的链接

指向原始笔记的链接

关联数据的查询

文档

  • child::

    内嵌文档

    • 内嵌文档的结构一般都是按照服务端定义的字段结构
      • 每个字段都附有一个文档,没有字段,就没有文档
        • 示例:一个字段对应一个解释
      • 所以不会像笔记一样为了方便理解、归类,而把接口分类
      • 所以嵌入文档都是直接对接实际业务的

    使用教程

    实例

    github graphAPI

    指向原始笔记的链接
  • child::

    graphQL schema与嵌入文档的关系

    示例

    github

    • 嵌入文档也是从服务端同一个端点中使用graphQL请求获取的
          - 按照一定结构规则用指定字段存储type的数据
    • schema中包含了嵌入文档的相关字段
          - 通常是某个类型的描述、参数、等信息
    指向原始笔记的链接

关联数据的查询

适用范围

优点

  • 可以减少网络请求次数,提高性能。
  • 可以让客户端精确地获取所需的数据,没有任何冗余。
  • 可以让 API 更易于演化,并启用强大的开发人员工具。
    • 无需打破原有的结构
  • 可以让客户端指定其需要的数据形状和粒度,从而减少了不必要的数据传输,提高了性能。
  • 提供了一个图形化的IDE,非常快速方便的编写接口请求代码
  • 单一端口,即单一请求链接
        - 如github的:https://api.github.com/graphql

缺点

  • 学习成本较高。
  • 对于简单的 API,GraphQL 可能会增加复杂性。
    • 需要多创建和修改一个schema
  • 性能问题
    • 对于需要大量计算的查询,GraphQL 可能会导致性能问题。
    • 资源增加需要更多的内存
  • 权限需要细化到字段
  • 缓存机制复杂

示例

GitHub 的graphQL

https://docs.github.com/en/graphql

  • 文档不是很详细、可读性不强
        - 不如RESTful API的文档细致
            - 建议先看RESTful API的文档,了解业务流程,再使用graphQL