当前位置: 首页 > news >正文

什么是GraphQL?

如果你在寻找漏洞利用方式,请参考下面的文章

GraphQL API 漏洞 |网络安全学院
GitHub - swisskyrepo/PayloadsAllTheThings: A list of useful payloads and bypass for Web Application Security and Pentest/CTF

GraphQL 查询(Query)

GraphQL 既不是架构,也不是数据库。它是一种 查询语言运行时环境,用于 API 的数据查询和操作。

假设你有一个使用关系型数据库(如 MySQL 或 PostgreSQL)的应用,数据库中存储了用户信息和文章数据。你可以通过 GraphQL 构建一个 API,它允许客户端按需查询用户信息和文章内容:

  • 你可以通过 GraphQL 查询来请求某个用户的基本信息和他的文章:
    {user(id: 1) {nameemailposts {titlecontent}}}
  • GraphQL 会将这个请求转发到服务器端,服务器端会通过数据库查询(例如 SQL 查询)获取数据,然后将结果返回给客户端。

响应可能看起来是这样的

{"data": {"user": {"name": "张三","email": "zhangsan@example.com","posts": [{"title": "GraphQL简介","content": "GraphQL是一种用于API的查询语言和运行时环境。"},{"title": "Apollo Server使用指南","content": "Apollo Server是一个用于构建GraphQL服务器的库。"}]}}
}

所以,GraphQL 是一种 灵活的数据查询工具,它位于应用的 API 层,能让客户端高效地与不同的数据源交互,但它本身不负责数据库的存储和管理。

GraphQL 结构与类型信息

在 GraphQL 中,结构类型信息 主要指的是 API 中的 数据模型查询接口,它们描述了你可以查询的数据的组织形式和每个数据字段的类型。通过这些信息,客户端能够了解如何正确地查询 API,以及 API 返回的每个字段的数据类型是什么。下面是对这些术语的详细解释。

1. GraphQL API 的结构

结构 指的是 GraphQL 服务的 整体设计,包括:

  • 类型(Types):GraphQL API 中定义的各种数据类型。例如,UserPostComment 等,通常表示你在应用中处理的数据模型。
  • 字段(Fields):每个类型下的字段,这些字段是 GraphQL 查询的结果。例如,一个 User 类型可能有 idnameemail 等字段。
  • 查询(Queries)变更(Mutations)订阅(Subscriptions):这些是你可以对 API 执行的操作。查询用于获取数据,变更用于修改数据,订阅用于实时接收数据更新。

2. GraphQL API 的类型信息

类型信息 指的是 API 中各个类型的具体定义和它们之间的关系。这些信息包括:

2.1 基本类型(Scalar Types)

GraphQL 提供了几种基本的标量类型,用于描述单一值的类型:

  • Int:整数
  • Float:浮动点数
  • String:字符串
  • Boolean:布尔值(truefalse
  • ID:唯一标识符,通常用作主键(类似于 UUID
2.2 对象类型(Object Types)

对象类型是 GraphQL 中最常见的类型,用于定义一个包含多个字段的数据结构。例如,一个 User 类型可能定义如下:

type User {id: ID!name: String!email: Stringposts: [Post]
}
  • User 类型包含了几个字段,如 id(ID 类型,必需)、name(String 类型,必需)、email(String 类型,非必需)、posts(一个 Post 类型的数组,表示该用户的所有帖子)。
  • ID! 表示 id 字段是必需的(非 null)。
  • posts 字段是一个 数组,并且是 Post 类型的数组,这意味着每个用户可能有多个帖子。
2.3 输入类型(Input Types)

输入类型用于描述查询或变更请求中传递的数据结构。例如,一个 CreateUser 类型可以定义如何创建一个用户:

input CreateUser {name: String!email: String!
}
  • CreateUser 类型定义了创建用户时需要提供的字段,nameemail 都是必需的。
2.4 枚举类型(Enum Types)

枚举类型用于定义一组固定的值。例如,定义用户角色的枚举类型:

enum Role {ADMINUSERGUEST
}
  • Role 枚举类型包含了三个可能的值:ADMINUSERGUEST,这些可以用于限制字段的输入值。
2.5 接口类型(Interface Types)

接口类型允许你定义一组共享字段的类型。比如,我们可以定义一个 Node 接口,使得多个类型都继承这个接口,保证它们有相同的字段:

interface Node {id: ID!
}type User implements Node {id: ID!name: String!
}type Post implements Node {id: ID!title: String!
}
  • Node 接口有一个 id 字段,任何实现了这个接口的类型(如 UserPost)都必须拥有 id 字段。
2.6 联合类型(Union Types)

联合类型允许一个字段返回多种类型中的任意一种。与接口类似,但联合类型不强制实现相同的字段,只是定义了多个可能返回的类型:

union SearchResult = User | Post
  • SearchResult 可以是 UserPost,具体返回哪一个类型由实际查询的结果决定。

GraphQL 内省(Introspection)

GraphQL 内省(Introspection) 是 GraphQL 的一个强大特性,它允许客户端查询 GraphQL API 的 结构类型信息,而不仅仅是查询应用程序的数据。通过内省,客户端可以动态地了解 GraphQL API 的模式、类型、查询、变更等元数据。

内省的工作原理

GraphQL 内省是通过一种特别的查询实现的,通常叫做 内省查询(Introspection Query)。这些查询返回关于 GraphQL API 的详细信息,比如:

  • 类型:查询支持的类型(如 QueryMutationSubscription 类型及其字段)。
  • 字段:每个类型下的字段及其类型。
  • 输入类型:GraphQL API 中支持的输入类型。
  • 枚举类型:GraphQL API 中定义的枚举类型及其可能的值。
  • 错误信息:每个字段可能返回的错误类型。

简单来说,内省使得客户端能够自我探索 API 的结构,而不需要依赖文档或其他外部信息。

一个典型的内省查询例子

一个典型的内省查询示例如下:

{__schema {types {name}}
}

这个查询会返回所有在 GraphQL API 中定义的类型的名称。你可以利用内省查询获得更详细的信息,比如查看每个类型的字段、字段的返回类型、查询或变更的定义等。

常见的内省查询示例

  1. 获取所有类型

    {__schema {types {name}}
    }
    

    这个查询返回 API 中的所有类型。

  2. 获取类型字段
    如果你想查询某个特定类型的字段,可以使用类似如下的查询:

    {__type(name: "User") {fields {nametype {name}}}
    }
    

    这个查询返回 User 类型的字段及其类型。

  3. 获取某个字段的详细信息
    比如查询某个字段的数据类型和输入类型:

    {__type(name: "User") {fields {nameargs {nametype {name}}}}
    }
    

某些 GraphQL 服务器允许禁用内省查询,尤其是在生产环境中,以提高安全性。例如,使用 Apollo Server 时,你可以通过设置 introspection 配置来禁用内省:

const server = new ApolloServer({schema,introspection: false, // 禁用内省
});

GraphQL 突变(Mutation)

GraphQL 突变(Mutation) 是 GraphQL 中的一种操作类型,用于 修改数据。与查询(Query)不同,查询用于 获取数据,而突变用于对数据进行 创建、更新或删除 操作。

1. 突变的基本概念

在 GraphQL 中,Mutation 是一种特定的操作类型,就像 Query 用来请求数据一样,Mutation 用来处理数据修改请求。每个突变操作通常会返回修改后的数据,或者返回表示操作结果的信息。

突变操作 的目标通常是数据库的更改,比如:

  • 创建一个新记录(如添加用户、发布文章等)。
  • 更新一个已有记录(如修改用户信息、修改文章内容等)。
  • 删除一个记录(如删除用户、删除文章等)。

2. GraphQL 突变的定义

在 GraphQL schema 中,Mutation 类型是专门用来定义数据修改操作的。例如:

type Mutation {createUser(name: String!, email: String!): UserupdateUser(id: ID!, name: String, email: String): UserdeleteUser(id: ID!): Boolean
}

这里定义了三个突变操作:

  • createUser:创建一个新的用户,返回一个 User 类型的对象。
  • updateUser:更新用户的信息,接受用户的 id 和可选的 nameemail,返回更新后的 User 对象。
  • deleteUser:删除一个用户,返回一个布尔值(truefalse),表示删除操作是否成功。

3. 突变的执行

执行突变时,你会发送一个包含特定操作和参数的请求。例如,要创建一个用户,你可以这样写:

mutation {createUser(name: "Alice", email: "alice@example.com") {idnameemail}
}

在这个突变请求中:

  • mutation 关键字表示这是一个突变请求。
  • createUser 是我们在 schema 中定义的突变操作。
  • nameemailcreateUser 操作需要的参数。
  • 你可以指定想要返回的字段,比如返回新创建的用户的 idnameemail

4. 突变的响应

执行突变后,服务器会返回执行结果。例如,上面的 createUser 突变成功时,服务器可能返回如下结果:

{"data": {"createUser": {"id": "1","name": "Alice","email": "alice@example.com"}}
}

返回的数据会包含你在请求中指定的字段(如 idnameemail)。

5. 突变的特点

  • 数据修改:突变通常用于改变数据的状态(创建、更新、删除)。
  • 副作用:突变操作通常会有副作用,可能涉及到数据库更新、缓存修改等。
  • 同步与返回:突变操作通常会返回修改后的数据,或者操作是否成功的反馈(如布尔值)。
  • 可以返回多个字段:虽然突变修改了数据,但你依然可以指定哪些字段返回给客户端,确保客户端可以在修改后获得最新的数据。

6. 突变和查询的区别

  • 查询(Query):用于 读取数据,无副作用,不会改变服务器上的任何数据。
  • 突变(Mutation):用于 修改数据,会产生副作用,可能涉及创建、更新、删除操作。

一个典型的查询请求示例:

query {getUser(id: "1") {idnameemail}
}

一个典型的突变请求示例:

mutation {updateUser(id: "1", name: "Alice Updated", email: "aliceupdated@example.com") {idnameemail}
}

7. 如何处理多个突变

GraphQL 允许你在一个请求中执行多个突变,但它们的执行是 顺序的,并且所有的突变都必须成功,才能返回一个完整的响应。比如,你可以在一个请求中同时更新用户的 nameemail

mutation {updateUser(id: "1", name: "Alice Updated") {idname}updateUser(id: "1", email: "aliceupdated@example.com") {idemail}
}

8. 突变和错误处理

突变操作有可能会失败,通常由于参数不正确、数据不存在或者权限问题等。GraphQL 的错误处理机制允许返回详细的错误信息。例如,如果 updateUser 操作传入了无效的 id,响应可能如下:

{"errors": [{"message": "User not found","locations": [{ "line": 2, "column": 3 }],"path": ["updateUser"],"extensions": {"code": "USER_NOT_FOUND"}}],"data": null
}

相关文章:

什么是GraphQL?

如果你在寻找漏洞利用方式,请参考下面的文章 GraphQL API 漏洞 |网络安全学院 GitHub - swisskyrepo/PayloadsAllTheThings: A list of useful payloads and bypass for Web Application Security and Pentest/CTF GraphQL 查询(Query) GraphQL 既不是…...

Spring Boot 的约定优于配置,你的理解是什么?

Spring Boot 的“约定优于配置”:开发效率的革命性提升 在软件开发中,开发者常常需要花费大量时间编写繁琐的配置文件,尤其是在传统的 Java EE 或 Spring 框架中。而 Spring Boot 通过“约定优于配置”(Convention Over Configur…...

C#开源大型商城系统之B2B2C+O2O一体化_OctShop

一、应用背景与引言 在当今数字化商业的浪潮中,电子商务平台的构建成为众多企业拓展业务、提升竞争力的关键举措。C# 语言以其强大的功能、高效的性能以及良好的开发框架支持,在商城系统开发领域占据着重要地位。独立开源的大型 C# 商城系统&#xff0c…...

gitte远程仓库修改后,本地没有更新,本地与远程仓库不一致

问题 :gitte远程仓库修改后,本地没有更新,本地与远程仓库不一致 现象: [cxqiZwz9fjj2ssnshikw14avaZ rpc]$ git push Username for https://gitee.com: beihangya Password for https://beihangyagitee.com: To https://gitee.c…...

【对比】Pandas 和 Polars 的区别

Pandas vs Polars 对比表 特性PandasPolars开发语言Python(Cython 实现核心部分)Rust(高性能系统编程语言)性能较慢,尤其在大数据集上(内存占用高,计算效率低)极快,利用…...

el-input无法输入0.0001的小数,自动转换为0在vue3中的bug

今天遇到个bug&#xff0c;el-input中只能输入0.1或者输入0.1再加上00成为0.001&#xff0c;不能直接输入0.001&#xff0c;否则自动转换为0。需要去掉 v-model.number后面的 .number 源代码&#xff1a; <el-table-column label"实发数量" width"120"…...

Ubuntu 下 systemd 介绍

系列文章目录 Linux内核学习 Linux 知识&#xff08;1&#xff09; Linux 知识&#xff08;2&#xff09; WSL Ubuntu QEMU 虚拟机 Linux 调试视频 PCIe 与 USB 的补充知识 vscode 使用说明 树莓派 4B 指南 设备驱动畅想 Linux内核子系统 Linux 文件系统挂载 QEMU 通过网络实现…...

BERT文本分类(PyTorch和Transformers)畅用七个模型架构

&#xff08;PyTorch&#xff09;BERT文本分类&#xff1a;七种模型架构 &#x1f31f; 1. 介绍 使用BERT完成文本分类任务&#xff08;如情感分析&#xff0c;新闻文本分类等等&#xff09;对于NLPer已经是很基础的工作了&#xff01;虽说已迈入LLM时代&#xff0c;但是BERT…...

两步在 Vite 中配置 Tailwindcss

第一步&#xff1a;安装依赖 npm i -D tailwindcss tailwindcss/vite第二步&#xff1a;引入 tailwindcss 更改配置 // src/main.js import tailwindcss/index// vite.config.js import vue from vitejs/plugin-vue import tailwindcss from tailwindcss/viteexport default …...

【vmware虚拟机安装教程】

以下是在VMware Workstation Pro上安装虚拟机的详细教程&#xff1a; 准备工作 下载VMware Workstation Pro 访问VMware官网下载并安装VMware Workstation Pro&#xff08;支持Windows和Linux系统&#xff09;。安装完成后&#xff0c;确保已激活软件&#xff08;试用版或正式…...

文字转语音(三)FreeTTS实现

项目中有相关的功能&#xff0c;就简单研究了一下。 说明 FreeTTS 是一个基于 Java 的开源文本转语音&#xff08;TTS&#xff09;引擎&#xff0c;旨在将文字内容转换为自然语音输出。 FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景&#xff0c;但若需…...

string类详解(上)

文章目录 目录1. STL简介1.1 什么是STL1.2 STL的版本1.3 STL的六大组件 2. 为什么学习string类3. 标准库中的string类3.1 string类3.2 string类的常用接口说明 目录 STL简介为什么学习string类标准库中的string类string类的模拟实现现代版写法的String类写时拷贝 1. STL简介 …...

Visual Studio Code使用ai大模型编成

1、在Visual Studio Code搜索安装roo code 2、去https://openrouter.ai/settings/keys官网申请个免费的配置使用...

外贸跨境订货系统流程设计、功能列表及源码输出

在全球化的商业环境下&#xff0c;外贸跨境订货系统对于企业拓展国际市场、提升运营效率至关重要。该系统旨在为外贸企业提供一个便捷、高效、安全的订货平台&#xff0c;实现商品展示、订单管理、物流跟踪等功能&#xff0c;满足跨境业务的多样化需求。以下将详细阐述外贸订货…...

TraeAi上手体验

一、Trae介绍 由于MarsCode 在国内由于规定限制&#xff0c;无法使用 Claude 3.5 Sonnet 模型&#xff0c;字节跳动选择在海外推出 Trae&#xff0c;官网&#xff1a;https://www.trae.ai/。 二、安装 1.下载安装Trae-Setup-x64.exe 2.注册登录 安装完成后&#xff0c;点击登…...

深入解析 vLLM:高性能 LLM 服务框架的架构之美(一)原理与解析

修改内容时间2.4.1处理请求的流程&#xff0c;引用更好的流程图2025.02.11首发2025.02.08 深入解析 vLLM&#xff1a;高性能 LLM 服务框架的架构之美&#xff08;一&#xff09;原理与解析 深入解析 vLLM&#xff1a;高性能 LLM 服务框架的架构之美&#xff08;二&#xff09;…...

thingboard告警信息格式美化

原始报警json内容&#xff1a; { "severity": "CRITICAL","acknowledged": false,"cleared": false,"assigneeId": null,"startTs": 1739801102349,"endTs": 1739801102349,"ackTs": 0,&quo…...

redis解决高并发看门狗策略

当一个业务执行时间超过自己设定的锁释放时间&#xff0c;那么会导致有其他线程进入&#xff0c;从而抢到同一个票,所有需要使用看门狗策略&#xff0c;其实就是开一个守护线程&#xff0c;让守护线程去监控key&#xff0c;如果到时间了还未结束&#xff0c;就会将这个key重新s…...

Python函数的函数名250217

函数名其实就是一个变量&#xff0c;这个变量就是代指函数而已函数也可以被哈希&#xff0c;所以函数名也可以当作集合中的元素&#xff0c;也可作为字典的key值 # 将函数作为字典中的值&#xff0c;可以避免写大量的if...else语句 def fun1():return 123 def fun2():return 4…...

Unity 获取独立显卡数量

获取独立显卡数量 导入插件包打开Demo 运行看控制台日志 public class GetGraphicCountDemo : MonoBehaviour{public int count;// Start is called before the first frame updatevoid Start(){count this.GetIndependentGraphicsDeviceCount();}}...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...