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

前端 GraphQL:别再为 API 调用头疼了

前端 GraphQL别再为 API 调用头疼了什么是前端 GraphQLGraphQL 是一种用于 API 的查询语言也是一个满足你数据查询的运行时。别以为 GraphQL 只是一种新的 API 格式它是前端数据获取的革命性解决方案。为什么需要前端 GraphQL精确获取数据只获取需要的数据避免过度获取减少网络请求一次请求获取所有需要的数据类型安全GraphQL 有强类型系统提供更好的开发体验自我文档化GraphQL schema 自动生成文档实时数据支持订阅实现实时数据更新前端驱动前端可以自主决定需要的数据结构跨平台可以在浏览器、移动端等多个平台使用前端 GraphQL 核心概念1. 查询 (Query)查询用于从服务器获取数据类似于 REST 中的 GET 请求。# 基本查询 query GetUser { user(id: 1) { id name email posts { title content } } } # 带变量的查询 query GetUser($id: ID!) { user(id: $id) { id name email } } # 带参数的查询 query GetPosts { posts(first: 10, after: cursor) { edges { node { id title content } cursor } pageInfo { hasNextPage endCursor } } }2. 变更 (Mutation)变更用于修改服务器上的数据类似于 REST 中的 POST、PUT、DELETE 请求。# 创建用户 mutation CreateUser { createUser(input: { name: John Doe email: johnexample.com }) { user { id name email } } } # 更新用户 mutation UpdateUser($id: ID!, $input: UpdateUserInput!) { updateUser(id: $id, input: $input) { user { id name email } } } # 删除用户 mutation DeleteUser($id: ID!) { deleteUser(id: $id) { success } }3. 订阅 (Subscription)订阅用于获取实时更新的数据。# 订阅新帖子 subscription NewPost { postCreated { id title content author { id name } } } # 订阅用户状态变化 subscription UserStatusChanged { userStatusChanged(userId: 1) { userId status lastSeen } }4. SchemaSchema 定义了 GraphQL API 的类型和操作。# 类型定义 type User { id: ID! name: String! email: String! posts: [Post!]! } type Post { id: ID! title: String! content: String! author: User! createdAt: String! } # 输入类型 input CreateUserInput { name: String! email: String! password: String! } input UpdateUserInput { name: String email: String } # 查询类型 type Query { user(id: ID!): User users(first: Int, after: String): [User!]! post(id: ID!): Post posts(first: Int, after: String): [Post!]! } # 变更类型 type Mutation { createUser(input: CreateUserInput!): User! updateUser(id: ID!, input: UpdateUserInput!): User! deleteUser(id: ID!): Boolean! createPost(input: CreatePostInput!): Post! updatePost(id: ID!, input: UpdatePostInput!): Post! deletePost(id: ID!): Boolean! } # 订阅类型 type Subscription { postCreated: Post! userStatusChanged(userId: ID!): UserStatus! } type UserStatus { userId: ID! status: String! lastSeen: String! }前端 GraphQL 客户端1. Apollo ClientApollo Client 是最流行的 GraphQL 客户端之一提供了丰富的功能。// 安装 Apollo Client // npm install apollo/client graphql // 初始化 Apollo Client import { ApolloClient, InMemoryCache, ApolloProvider, gql } from apollo/client; const client new ApolloClient({ uri: https://api.example.com/graphql, cache: new InMemoryCache() }); // 使用 Apollo Provider function App() { return ( ApolloProvider client{client} div.../div /ApolloProvider ); } // 执行查询 const GET_USERS gql query GetUsers { users { id name email } } ; function Users() { const { loading, error, data } useQuery(GET_USERS); if (loading) return pLoading.../p; if (error) return pError: {error.message}/p; return ( ul {data.users.map(user ( li key{user.id} {user.name} - {user.email} /li ))} /ul ); } // 执行变更 const CREATE_USER gql mutation CreateUser($input: CreateUserInput!) { createUser(input: $input) { id name email } } ; function CreateUserForm() { const [name, setName] useState(); const [email, setEmail] useState(); const [password, setPassword] useState(); const [createUser, { loading, error }] useMutation(CREATE_USER); const handleSubmit (e) { e.preventDefault(); createUser({ variables: { input: { name, email, password } } }); }; return ( form onSubmit{handleSubmit} input typetext value{name} onChange{(e) setName(e.target.value)} placeholderName / input typeemail value{email} onChange{(e) setEmail(e.target.value)} placeholderEmail / input typepassword value{password} onChange{(e) setPassword(e.target.value)} placeholderPassword / button typesubmit disabled{loading} {loading ? Creating... : Create User} /button {error pError: {error.message}/p} /form ); } // 使用订阅 const NEW_POST gql subscription NewPost { postCreated { id title content author { id name } } } ; function PostFeed() { const { data, loading } useSubscription(NEW_POST); if (loading) return pLoading.../p; return ( div h2New Post/h2 {data ( div h3{data.postCreated.title}/h3 p{data.postCreated.content}/p pBy: {data.postCreated.author.name}/p /div )} /div ); }2. RelayRelay 是 Facebook 开发的 GraphQL 客户端专注于性能和开发者体验。// 安装 Relay // npm install relay-runtime relay-compiler react-relay // 配置 Relay import { Environment, Network, RecordSource, Store } from relay-runtime; function fetchQuery(operation, variables) { return fetch(https://api.example.com/graphql, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ query: operation.text, variables, }), }).then(response { return response.json(); }); } const environment new Environment({ network: Network.create(fetchQuery), store: new Store(new RecordSource()), }); // 使用 Relay Provider function App() { return ( RelayEnvironmentProvider environment{environment} div.../div /RelayEnvironmentProvider ); } // 执行查询 // 使用 relay-compiler 编译 GraphQL 查询 // relay-compiler --src ./src --schema ./schema.graphql function UserList() { const { data, error, isLoading } useLazyLoadQuery( graphql query UserListQuery { users { id name email } } , {} ); if (isLoading) return pLoading.../p; if (error) return pError: {error.message}/p; return ( ul {data.users.map(user ( li key{user.id} {user.name} - {user.email} /li ))} /ul ); }3. UrqlUrql 是一个轻量级的 GraphQL 客户端提供了简单的 API。// 安装 Urql // npm install urql graphql // 初始化 Urql import { createClient, Provider, useQuery, useMutation, useSubscription } from urql; const client createClient({ url: https://api.example.com/graphql, }); // 使用 Urql Provider function App() { return ( Provider value{client} div.../div /Provider ); } // 执行查询 function Users() { const [result] useQuery({ query: query GetUsers { users { id name email } } , }); const { data, fetching, error } result; if (fetching) return pLoading.../p; if (error) return pError: {error.message}/p; return ( ul {data.users.map(user ( li key{user.id} {user.name} - {user.email} /li ))} /ul ); } // 执行变更 function CreateUserForm() { const [name, setName] useState(); const [email, setEmail] useState(); const [result, executeMutation] useMutation( mutation CreateUser($name: String!, $email: String!) { createUser(input: { name: $name email: $email }) { user { id name email } } } ); const handleSubmit (e) { e.preventDefault(); executeMutation({ name, email, }); }; if (result.fetching) return pCreating.../p; if (result.error) return pError: {result.error.message}/p; return ( form onSubmit{handleSubmit} input typetext value{name} onChange{(e) setName(e.target.value)} placeholderName / input typeemail value{email} onChange{(e) setEmail(e.target.value)} placeholderEmail / button typesubmitCreate User/button /form ); }前端 GraphQL 最佳实践1. 查询优化只请求需要的字段避免过度获取数据使用片段重用查询片段减少代码重复分页使用分页获取大量数据缓存合理使用缓存减少网络请求预取预取可能需要的数据2. 变更处理乐观更新先更新本地缓存再等待服务器响应错误处理妥善处理变更错误重试机制对网络错误进行重试批量操作将多个变更合并为一个请求3. 订阅使用合理使用订阅只对需要实时更新的数据使用订阅订阅管理及时取消不需要的订阅错误处理妥善处理订阅错误重连机制在连接断开时自动重连4. 缓存策略缓存失效在数据变更后及时更新缓存缓存预热预加载常用数据到缓存缓存大小合理设置缓存大小避免内存占用过大缓存持久化将缓存持久化到本地存储5. 开发工具GraphiQL用于测试 GraphQL 查询Apollo Studio用于监控和调试 GraphQL APIRelay Compiler用于编译 Relay 查询ESLint GraphQL用于检查 GraphQL 查询的语法前端 GraphQL 案例1. 案例一GitHub APIGitHub API 使用 GraphQL 提供了丰富的功能允许开发者精确获取需要的数据。2. 案例二Shopify Storefront APIShopify Storefront API 使用 GraphQL 提供了灵活的电子商务功能允许前端精确获取产品、订单等数据。3. 案例三ContentfulContentful 使用 GraphQL 提供了内容管理功能允许前端精确获取需要的内容数据。4. 案例四HasuraHasura 提供了自动生成 GraphQL API 的功能大大简化了后端开发。前端 GraphQL 常见问题1. 问题一GraphQL 学习曲线GraphQL 有一定的学习曲线需要时间掌握。解决方法是从简单的查询开始逐步学习更复杂的功能。2. 问题二服务器端实现复杂GraphQL 服务器端实现可能比 REST 更复杂。解决方法是使用成熟的 GraphQL 服务器框架如 Apollo Server、Express GraphQL 等。3. 问题三缓存管理复杂GraphQL 缓存管理可能比 REST 更复杂。解决方法是使用成熟的 GraphQL 客户端如 Apollo Client它提供了强大的缓存管理功能。4. 问题四性能问题如果不注意查询优化GraphQL 可能会导致性能问题。解决方法是合理使用查询片段、分页、缓存等技术。总结前端 GraphQL 是前端数据获取的革命性解决方案它允许前端精确获取需要的数据减少网络请求提供更好的开发体验。别再为 API 调用头疼了GraphQL 已经来了记住GraphQL 不是 REST 的替代品而是 REST 的补充。它们各自有自己的优势应该根据具体场景选择合适的技术。别再忽视 GraphQL 了它是前端开发的未来趋势

相关文章:

前端 GraphQL:别再为 API 调用头疼了

前端 GraphQL:别再为 API 调用头疼了 什么是前端 GraphQL? GraphQL 是一种用于 API 的查询语言,也是一个满足你数据查询的运行时。别以为 GraphQL 只是一种新的 API 格式,它是前端数据获取的革命性解决方案。 为什么需要前端 Grap…...

前端 WebAssembly:别再抱怨 JavaScript 性能慢了

前端 WebAssembly:别再抱怨 JavaScript 性能慢了 什么是前端 WebAssembly? WebAssembly(简称 Wasm)是一种低级的编译目标,允许用 C、C、Rust 等语言编写的代码在浏览器中运行,性能接近原生应用。别以为 Web…...

10 款研发协同平台深度比较:从需求到测试到交付,哪款更顺手?

本文将深入对比 10 款主流研发一体化协同平台:PingCode、Worktile、Jira Confluence、GitLab、Azure DevOps、GitHub Enterprise、Linear、阿里云效、 CodeArts、CODING DevOps。现在很多企业做研发协同,真正难的不是缺工具,而是工具太多、太…...

实测对比:OpenCV微信QRCode vs ZXing二维码识别性能(附C++测试代码)

OpenCV微信QRCode与ZXing二维码识别引擎深度性能评测 二维码识别技术早已渗透到我们生活的方方面面,从移动支付到工业自动化,不同场景对识别引擎的性能要求差异显著。最近OpenCV 4.5.1整合了微信开源的QRCode识别模块,号称在速度和准确率上都…...

深入浅出讲解操作系统——实时调度

目录 ⏱️ 实时调度 第1课:什么是实时系统? 🎓 第一部分:专业学术讲解 1. 什么是实时系统? 2. 两种实时系统 🎓 第二部分:实时任务的关键概念 1️⃣ 截止时间(Deadline&#…...

深入解析Buffer在存储器电路设计中的关键作用:驱动能力与负载优化

1. 为什么Buffer是存储器电路设计的隐形英雄? 第一次接触存储器电路设计时,我和很多初学者一样,觉得Buffer(缓冲器)就是个简单的信号中转站。直到某次调试DDR4内存模块,时钟信号出现严重畸变,才…...

告别统计软件困境:虎贲等考 AI,让数据分析从 “硬核难题” 变 “轻松通关”

在学术研究与论文写作中,数据分析一直是横在学生与研究者面前的 “高门槛”。无论是本科毕业论文的基础统计,还是硕博期刊论文的实证检验,从数据清洗、模型构建到结果输出、图表制作,每一步都考验着专业能力。传统工具如 SPSS、St…...

射频新手避坑指南:功放输出匹配到4次谐波,这几个ADS Optim设置千万别搞错

射频功放设计实战:ADS Optim参数设置避坑手册 在射频功放设计中,输出匹配网络的设计质量直接影响着功放的效率、线性度和输出功率等关键指标。许多初学者在使用ADS(Advanced Design System)进行匹配电路优化时,常常陷入…...

轻榴浏览器:仅几MB的“轻功高手“,还你清净无扰的上网自由!

手机浏览器越来越臃肿——动辄几百MB的安装包,后台偷偷跑流量,刚搜个商品就收到精准广告推送,更别提那些关不掉的新闻资讯和弹窗骚扰……在这个"重口味"的浏览器时代,轻榴浏览器像一股清流逆势而来。这款体积小巧、基于…...

完整指南:5分钟掌握ImStudio实时GUI布局设计工具

完整指南:5分钟掌握ImStudio实时GUI布局设计工具 【免费下载链接】ImStudio GUI layout designer for Dear ImGui 项目地址: https://gitcode.com/gh_mirrors/im/ImStudio ImStudio是一款专为Dear ImGui开发者设计的实时GUI布局设计工具,它通过可…...

Unity WebGL实战:用AVProVideo搞定海康监控M3U8流播放(附XChart数据可视化技巧)

Unity WebGL实战:AVProVideo播放海康M3U8监控流与XChart数据可视化全解析 在数字孪生和安防监控领域,Unity WebGL项目集成实时视频流的需求日益增长。海康威视作为行业领先的监控设备供应商,其M3U8视频流格式在WebGL环境下的播放一直是个技术…...

Sentaurus TCAD实战——TCL脚本自动化仿真流程设计

1. 为什么需要TCL自动化仿真流程 第一次接触Sentaurus TCAD时,我像大多数工程师一样,在图形界面里点点鼠标完成仿真。但连续熬夜三天后,我发现每次修改参数都要重复点击20多个按钮,仿真100组参数意味着2000次机械操作。这种重复劳…...

鸿蒙ADB无线调试实战:从“积极拒绝”到稳定连接的避坑指南

1. 鸿蒙ADB无线调试的常见痛点 第一次尝试鸿蒙系统的ADB无线调试时,我遇到了那个经典的错误提示:"cannot connect to 192.168.1.101:5555: 由于目标计算机积极拒绝,无法连接。(10061)"。这个错误让我折腾了整整一个下午&#xff0c…...

《计算机组成原理》从零设计 CPU:深度拆解现代 RISC 处理器的通用数据通路与控制逻辑

本文内容深度参考了计算机体系结构领域的经典著作——《计算机组成与设计:硬件/软件接口》(Computer Organization and Design,简称 COAD)。 在学习 CPU 设计的过程中,我发现书中对数据通路的刻画极为精妙,…...

解锁专业音效:ViPER4Windows在Windows 10/11的完美运行方案

解锁专业音效:ViPER4Windows在Windows 10/11的完美运行方案 【免费下载链接】ViPER4Windows-Patcher Patches for fix ViPER4Windows issues on Windows-10/11. 项目地址: https://gitcode.com/gh_mirrors/vi/ViPER4Windows-Patcher 厌倦了ViPER4Windows在最…...

基于 Java 和高德开放平台的 WebAPI 集成实践——以“搜索 POI 2.0”为例

在位置服务类应用里,“找点”(Point of Interest,POI)几乎是最常见能力:输入“咖啡”“地铁站”“医院”,返回可用地点列表。 高德开放平台的 WebAPI 在这类场景中非常成熟,而 POI 2.0 相比早期…...

Redis数据库基础

NoSQL(内存/缓存型数据库): 相比于其他的内存/缓存数据库,redis可以方便的实现持久化的功能(保存至磁盘中)一、关系数据库与非关系数据库概述1、关系型数据库关系型数据库是一个结构化的数据库,…...

人工智能之知识蒸馏 第一章 绪论:知识蒸馏的基础认知

人工智能之知识蒸馏 第一章 绪论:知识蒸馏的基础认知 文章目录人工智能之知识蒸馏前言1.1 知识蒸馏的背景与意义1.2 知识蒸馏的核心定义与核心目标1.3 核心框架与学习目标核心流程图解配套代码实现(PyTorch示例)资料前言 1.1 知识蒸馏的背景…...

Java 大厂一面模拟:从活动发奖到消息幂等的分布式一致性拷问

开场说明 这是一场面向 1-3 年 Java 后端候选人或校招高阶候选人的模拟大厂一面,时长约 30 分钟。面试围绕一个典型的电商活动发奖业务场景展开,串联缓存设计、消息可靠性、事务一致性及分布式协调等核心模块。问题设计兼顾广度与深度,重点考…...

机器学习概念及学习目标

机器学习是计算机科学和人工智能的一个子领域,它通过对大量数据进行 分析,自动构建数学模型,从而能够在未见过的数据上进行预测、分类、 决策或生成内容。该算法通过训练数据优化模型参数,使模型能够根据输 入数据生成合理的输出。…...

Jetson orin nano 中安装docker

检查当前系统是否已经安装了 Docker,以及当前安装的版本号。通常在安装前运行它是为了确认是否需要安装: docker --version使用 curl 工具从 Docker 官方网站下载“一键安装脚本”,-fsSL 是一些静默下载和处理重定向的参数,-o ge…...

微型循环氩气金属气雾化制粉设备性价比高服务商

在材料科学的星辰大海中,金属粉末制备是通往3D打印、粉末冶金等前沿领域的基石。然而,对于无数高校课题组和中小型研发企业而言,这块“基石”却重若千钧——动辄三层楼高、耗气如流水、价格动辄百万的传统高压气雾化设备,如同一道…...

新手必读:计算机视觉需要哪些数学基础?如何高效学习线性代数和概率论?

新手必读:计算机视觉需要哪些数学基础?如何高效学习线性代数和概率论? 标签:#计算机视觉、#线性代数、#人工智能、#深度学习、#自然语言处理、#神经网络、#机器学习### 一、痛点引入:为什么很多人怕CV数学?…...

续讲wireshark——ECU测试实践记录

作为高效的以太网报文捕捉,也是测试手里的几件神器之一,wireshark的主要功用就是捕获报文。但也不仅仅只是开始捕获,结束捕获,保存文件,上传钉钉。wireshark入门首先的就是熟悉它的语法。捕获那么多东西,你…...

React 19新特性实战:3种方案实现组件自动刷新优化

在前端应用迭代中,组件不必要的重复渲染一直是性能优化的核心痛点,尤其在数据密集型场景中,频繁刷新不仅会拖慢页面响应速度,还会增加用户设备的资源消耗。React 19针对这一问题推出了多项底层优化,同时提供了更精细化…...

从零构建pix2pix训练集:数据准备与预处理实战

1. 理解pix2pix的数据需求 pix2pix作为经典的图像到图像转换模型,对训练数据有着特殊的要求。我第一次接触这个模型时,最头疼的就是数据准备环节。与普通分类任务不同,pix2pix需要的是成对的图像数据——简单说就是每张输入图片都要有对应的目…...

Kuikly框架性能深度解析:原生级跨端体验如何实现?

Kuikly 是腾讯大前端Oteam基于 Kotlin Multiplatform 开发的跨端框架。其技术设计使其在包体积、渲染效率等核心性能指标上,展现出特定优势。 1. 包体积极致轻量Android平台:AOT模式下仅约300KB iOS平台:约1.2MB Web版本:仅463K…...

手眼标定实战:从千米误差到毫米精度的关键技巧

1. 手眼标定为什么会出现"千米误差"? 第一次做手眼标定的同学,看到结果时可能会吓一跳——明明相机就装在机械臂末端,计算结果却显示两者相距上千米。这种情况我遇到过不止一次,记得有次在汽车装配线上调试,…...

ConvNeXt 系列改进:ConvNeXt 用于视频行为识别:3D ConvNeXt 改进与 Kinetics 实验

引言:当 ConvNeXt 遇上视频 2022年,Facebook AI Research提出的ConvNeXt在计算机视觉领域投下了一颗重磅炸弹。它以纯卷积结构达到了87.8%的ImageNet Top-1精度,在COCO检测和ADE20K分割任务上甚至超越了当时风头正劲的Swin Transformer,证明了“卷积并未死去,只是需要被现…...

[具身智能-364]:LeRobot 不是通用机器人控制系统(如 ROS2 导航/规划栈),而是专注于“感知-决策-动作”端到端学习的 AI 框架。他们共同成为具身智能时代最重要的开源基础设施之一

LeRobot 与 ROS2 并非替代关系,而是“智能生成”与“可靠执行”的双轨架构。二者共同构成了下一代机器人从“实验室原型”走向“物理世界部署”的基石。以下从定位差异、架构协同、融合挑战、演进趋势四个维度进行系统阐述。🔍 一、核心定位与设计哲学&a…...