什么是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 中定义的各种数据类型。例如,
User
、Post
、Comment
等,通常表示你在应用中处理的数据模型。 - 字段(Fields):每个类型下的字段,这些字段是 GraphQL 查询的结果。例如,一个
User
类型可能有id
、name
、email
等字段。 - 查询(Queries)、变更(Mutations)、订阅(Subscriptions):这些是你可以对 API 执行的操作。查询用于获取数据,变更用于修改数据,订阅用于实时接收数据更新。
2. GraphQL API 的类型信息
类型信息 指的是 API 中各个类型的具体定义和它们之间的关系。这些信息包括:
2.1 基本类型(Scalar Types)
GraphQL 提供了几种基本的标量类型,用于描述单一值的类型:
- Int:整数
- Float:浮动点数
- String:字符串
- Boolean:布尔值(
true
或false
) - 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
类型定义了创建用户时需要提供的字段,name
和email
都是必需的。
2.4 枚举类型(Enum Types)
枚举类型用于定义一组固定的值。例如,定义用户角色的枚举类型:
enum Role {ADMINUSERGUEST
}
Role
枚举类型包含了三个可能的值:ADMIN
、USER
和GUEST
,这些可以用于限制字段的输入值。
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
字段,任何实现了这个接口的类型(如User
或Post
)都必须拥有id
字段。
2.6 联合类型(Union Types)
联合类型允许一个字段返回多种类型中的任意一种。与接口类似,但联合类型不强制实现相同的字段,只是定义了多个可能返回的类型:
union SearchResult = User | Post
SearchResult
可以是User
或Post
,具体返回哪一个类型由实际查询的结果决定。
GraphQL 内省(Introspection)
GraphQL 内省(Introspection) 是 GraphQL 的一个强大特性,它允许客户端查询 GraphQL API 的 结构 和 类型信息,而不仅仅是查询应用程序的数据。通过内省,客户端可以动态地了解 GraphQL API 的模式、类型、查询、变更等元数据。
内省的工作原理
GraphQL 内省是通过一种特别的查询实现的,通常叫做 内省查询(Introspection Query)。这些查询返回关于 GraphQL API 的详细信息,比如:
- 类型:查询支持的类型(如
Query
、Mutation
、Subscription
类型及其字段)。 - 字段:每个类型下的字段及其类型。
- 输入类型:GraphQL API 中支持的输入类型。
- 枚举类型:GraphQL API 中定义的枚举类型及其可能的值。
- 错误信息:每个字段可能返回的错误类型。
简单来说,内省使得客户端能够自我探索 API 的结构,而不需要依赖文档或其他外部信息。
一个典型的内省查询例子
一个典型的内省查询示例如下:
{__schema {types {name}}
}
这个查询会返回所有在 GraphQL API 中定义的类型的名称。你可以利用内省查询获得更详细的信息,比如查看每个类型的字段、字段的返回类型、查询或变更的定义等。
常见的内省查询示例
-
获取所有类型:
{__schema {types {name}} }
这个查询返回 API 中的所有类型。
-
获取类型字段:
如果你想查询某个特定类型的字段,可以使用类似如下的查询:{__type(name: "User") {fields {nametype {name}}} }
这个查询返回
User
类型的字段及其类型。 -
获取某个字段的详细信息:
比如查询某个字段的数据类型和输入类型:{__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
和可选的name
、email
,返回更新后的User
对象。deleteUser
:删除一个用户,返回一个布尔值(true
或false
),表示删除操作是否成功。
3. 突变的执行
执行突变时,你会发送一个包含特定操作和参数的请求。例如,要创建一个用户,你可以这样写:
mutation {createUser(name: "Alice", email: "alice@example.com") {idnameemail}
}
在这个突变请求中:
mutation
关键字表示这是一个突变请求。createUser
是我们在 schema 中定义的突变操作。name
和email
是createUser
操作需要的参数。- 你可以指定想要返回的字段,比如返回新创建的用户的
id
、name
和email
。
4. 突变的响应
执行突变后,服务器会返回执行结果。例如,上面的 createUser
突变成功时,服务器可能返回如下结果:
{"data": {"createUser": {"id": "1","name": "Alice","email": "alice@example.com"}}
}
返回的数据会包含你在请求中指定的字段(如 id
、name
、email
)。
5. 突变的特点
- 数据修改:突变通常用于改变数据的状态(创建、更新、删除)。
- 副作用:突变操作通常会有副作用,可能涉及到数据库更新、缓存修改等。
- 同步与返回:突变操作通常会返回修改后的数据,或者操作是否成功的反馈(如布尔值)。
- 可以返回多个字段:虽然突变修改了数据,但你依然可以指定哪些字段返回给客户端,确保客户端可以在修改后获得最新的数据。
6. 突变和查询的区别
- 查询(Query):用于 读取数据,无副作用,不会改变服务器上的任何数据。
- 突变(Mutation):用于 修改数据,会产生副作用,可能涉及创建、更新、删除操作。
一个典型的查询请求示例:
query {getUser(id: "1") {idnameemail}
}
一个典型的突变请求示例:
mutation {updateUser(id: "1", name: "Alice Updated", email: "aliceupdated@example.com") {idnameemail}
}
7. 如何处理多个突变
GraphQL 允许你在一个请求中执行多个突变,但它们的执行是 顺序的,并且所有的突变都必须成功,才能返回一个完整的响应。比如,你可以在一个请求中同时更新用户的 name
和 email
:
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# 商城系统,…...
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,el-input中只能输入0.1或者输入0.1再加上00成为0.001,不能直接输入0.001,否则自动转换为0。需要去掉 v-model.number后面的 .number 源代码: <el-table-column label"实发数量" width"120"…...

Ubuntu 下 systemd 介绍
系列文章目录 Linux内核学习 Linux 知识(1) Linux 知识(2) WSL Ubuntu QEMU 虚拟机 Linux 调试视频 PCIe 与 USB 的补充知识 vscode 使用说明 树莓派 4B 指南 设备驱动畅想 Linux内核子系统 Linux 文件系统挂载 QEMU 通过网络实现…...
BERT文本分类(PyTorch和Transformers)畅用七个模型架构
(PyTorch)BERT文本分类:七种模型架构 🌟 1. 介绍 使用BERT完成文本分类任务(如情感分析,新闻文本分类等等)对于NLPer已经是很基础的工作了!虽说已迈入LLM时代,但是BERT…...

两步在 Vite 中配置 Tailwindcss
第一步:安装依赖 npm i -D tailwindcss tailwindcss/vite第二步:引入 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上安装虚拟机的详细教程: 准备工作 下载VMware Workstation Pro 访问VMware官网下载并安装VMware Workstation Pro(支持Windows和Linux系统)。安装完成后,确保已激活软件(试用版或正式…...

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

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官网申请个免费的配置使用...

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

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

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

thingboard告警信息格式美化
原始报警json内容: { "severity": "CRITICAL","acknowledged": false,"cleared": false,"assigneeId": null,"startTs": 1739801102349,"endTs": 1739801102349,"ackTs": 0,&quo…...

redis解决高并发看门狗策略
当一个业务执行时间超过自己设定的锁释放时间,那么会导致有其他线程进入,从而抢到同一个票,所有需要使用看门狗策略,其实就是开一个守护线程,让守护线程去监控key,如果到时间了还未结束,就会将这个key重新s…...
Python函数的函数名250217
函数名其实就是一个变量,这个变量就是代指函数而已函数也可以被哈希,所以函数名也可以当作集合中的元素,也可作为字典的key值 # 将函数作为字典中的值,可以避免写大量的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内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,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任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

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

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 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的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...