当前位置: 首页 > 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();}}...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...