《Python实战进阶》专栏 No 5:GraphQL vs RESTful API 对比与实现
《Python实战进阶》专栏包括68集,每一集聚焦一个中高级技术知识点,涵盖Python在Web开发、数据处理、自动化、机器学习、并发编程等领域的应用,系统梳理Python开发者的知识集。本集的主题为: No4 : GraphQL vs RESTful API 对比与实现 ,第六集的主题为No6 : OAuth2.0 认证与授权的实现 。
第五集:GraphQL vs RESTful API 对比与实现
目录
- 引言
- RESTful API 简介与优缺点
- GraphQL 简介与优缺点
- GraphQL 与 RESTful API 的对比
- 实战:构建一个简单的 RESTful API 和 GraphQL API
- RESTful API 实现
- GraphQL API 实现
- 总结
1. 引言
在现代 Web 开发中,API 是前后端通信的核心。RESTful API 和 GraphQL 是两种主流的 API 设计方式,它们各有优劣,适用于不同的场景。本节将深入探讨两者的区别,并通过实战代码展示如何实现这两种 API。
2. RESTful API 简介与优缺点
RESTful API 是一种基于 HTTP 协议的架构风格,它通过 URL 定义资源,并使用 HTTP 方法(如 GET、POST、PUT、DELETE)对资源进行操作。

优点
- 简单直观:URL 明确表示资源,HTTP 方法清晰定义操作。
- 广泛支持:几乎所有编程语言和框架都支持 RESTful 风格。
- 缓存友好:HTTP 缓存机制可以直接应用于 RESTful API。
缺点
- 过度获取或不足获取数据:客户端无法灵活控制返回的数据结构,可能导致冗余或缺失。
- 版本管理复杂:随着需求变化,可能需要维护多个版本的 API。
3. GraphQL 简介与优缺点
GraphQL 是 Facebook 开发的一种查询语言,允许客户端精确指定所需的数据结构,从而避免了 RESTful API 的过度获取问题。

优点
- 灵活性:客户端可以自定义查询,只获取需要的数据。
- 单一入口:所有请求通过一个端点完成,简化了 API 设计。
- 强类型系统:GraphQL 提供了类型定义,便于开发和调试。
缺点
- 学习曲线较高:相比 RESTful API,GraphQL 的概念和实现更复杂。
- 性能问题:复杂的嵌套查询可能导致性能瓶颈。
- 工具生态相对较少:虽然 GraphQL 工具链日益完善,但仍不及 RESTful API 成熟。
4. GraphQL 与 RESTful API 的对比
| 特性 | RESTful API | GraphQL |
|---|---|---|
| 数据获取 | 固定结构,可能冗余或不足 | 灵活查询,按需获取 |
| 请求方式 | 多个端点,每个端点对应一个资源 | 单一端点,统一处理所有请求 |
| 缓存支持 | 原生支持 HTTP 缓存 | 需要额外实现缓存机制 |
| 学习难度 | 简单直观 | 概念较复杂,需要学习查询语言 |
| 性能优化 | 较容易优化 | 需要防止 N+1 查询等问题 |
5. 实战:构建一个简单的 RESTful API 和 GraphQL API
我们将以一个简单的任务管理系统为例,展示如何实现 RESTful API 和 GraphQL API。
环境准备
- Python 3.8+
- Flask(用于 RESTful API)
- Graphene(用于 GraphQL API)
安装依赖:
pip install flask graphene flask-graphql requests
数据模型
假设我们有一个任务列表,每项任务包含以下字段:
id: 任务 IDtitle: 任务标题description: 任务描述done: 是否完成
RESTful API 实现
创建文件 rest_api.py:
from flask import Flask, jsonify, requestapp = Flask(__name__)# 模拟的任务数据
tasks = [{"id": 1, "title": "Learn Python", "description": "Study Python basics", "done": False},{"id": 2, "title": "Write Code", "description": "Practice coding daily", "done": True},
]@app.route('/tasks', methods=['GET'])
def get_tasks():return jsonify(tasks)@app.route('/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):task = next((task for task in tasks if task["id"] == task_id), None)if task:return jsonify(task)return jsonify({"error": "Task not found"}), 404@app.route('/tasks', methods=['POST'])
def create_task():new_task = request.jsonnew_task["id"] = len(tasks) + 1tasks.append(new_task)return jsonify(new_task), 201if __name__ == '__main__':app.run(debug=True)
运行 RESTful API:
python rest_api.py
测试1:
curl http://127.0.0.1:5000/tasks
#或者在浏览器输入:
http://127.0.0.1:5000/tasks
程序输出:
[{"description": "Study Python basics","done": false,"id": 1,"title": "Learn Python"},{"description": "Practice coding daily","done": true,"id": 2,"title": "Write Code"}
]
测试2:
curl http://127.0.0.1:5000/tasks/1
#或者在浏览器输入:
http://127.0.0.1:5000/tasks/1
程序输出:
{"description": "Study Python basics","done": false,"id": 1,"title": "Learn Python"
}
测试3:
curl -X POST http://127.0.0.1:5000/tasks -H "Content-Type: application/json" -d "{\"title\":\"New Task\", \"description\": \"This is a new task\", \"done\": false}"
程序输出:
{"description": "This is a new task","done": false,"id": 4,"title": "New Task"
}
GraphQL API 实现
创建文件 graphql_api.py:
from flask import Flask
from flask_graphql import GraphQLView
from graphene import ObjectType, String, Boolean, List, Schema, Field, Int, Mutationapp = Flask(__name__)# 定义任务类型
class Task(ObjectType):id = Int()title = String()description = String()done = Boolean()# 模拟的任务数据
tasks = [Task(id=1, title="Learn Python", description="Study Python basics", done=False),Task(id=2, title="Write Code", description="Practice coding daily", done=True),
]# 查询根类型
class Query(ObjectType):tasks = List(Task)task = Field(Task, id=Int())def resolve_tasks(self, info):return tasksdef resolve_task(self, info, id):return next((task for task in tasks if task.id == id), None)# 变更根类型
class CreateTask(Mutation):class Arguments:title = String()description = String()done = Boolean()task = Field(Task)def mutate(self, info, title, description, done):new_task = Task(id=len(tasks) + 1, title=title, description=description, done=done)tasks.append(new_task)return CreateTask(task=new_task)class Mutation(ObjectType):create_task = CreateTask.Field()schema = Schema(query=Query, mutation=Mutation)# 添加 GraphQL 视图
app.add_url_rule('/graphql',view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True)
)if __name__ == '__main__':app.run(debug=True)
运行 GraphQL API:
python graphql_api.py
访问 http://127.0.0.1:5000/graphql,使用 GraphiQL 测试查询和变更。
示例查询:
{tasks {idtitledone}
}
示例变更:
mutation {createTask(title: "New Task", description: "Description", done: false) {task {idtitle}}
}
6. 总结
通过本节的学习,我们了解了 RESTful API 和 GraphQL 的核心概念及优缺点,并通过实战代码实现了两种 API。选择哪种技术取决于具体需求:如果需要简单易用的 API,RESTful 是不错的选择;如果需要灵活的数据查询能力,GraphQL 更加适合。
在下一集《OAuth2.0 认证与授权的实现》中,我们将探讨如何为 API 添加安全保护机制,敬请期待!
图示
- 图1:RESTful API 请求流程图
- 图2:GraphQL 查询流程图
希望本节内容对你有所帮助!
相关文章:
《Python实战进阶》专栏 No 5:GraphQL vs RESTful API 对比与实现
《Python实战进阶》专栏包括68集,每一集聚焦一个中高级技术知识点,涵盖Python在Web开发、数据处理、自动化、机器学习、并发编程等领域的应用,系统梳理Python开发者的知识集。本集的主题为: No4 : GraphQL vs RESTful API 对比与实…...
类和对象——static修饰类的成员
static修饰类的成员 static成员1 static成员的概念2 特性 static成员 有时会有这样的需求:计算程序中创建出了多少个类的对象,以及多少个正在使用的对象。 因为构造函数和析构函数都只会调用一次,所以可以通过设置生命周期和main函数一致的…...
RabbitMQ系列(七)基本概念之Channel
RabbitMQ 中的 Channel(信道) 是客户端与 RabbitMQ 服务器通信的虚拟会话通道,其核心作用在于优化资源利用并提升消息处理效率。以下是其核心机制与功能的详细解析: 一、Channel 的核心定义 虚拟通信链路 Channel 是建立在 TCP 连…...
你对 Spring Cloud 的理解
Spring Cloud 是一个基于 Spring Boot 的微服务架构开发工具集,为开发者提供了快速构建分布式系统的一系列解决方案,涵盖了服务发现、配置管理、熔断器、智能路由、微代理、控制总线等多个方面。 从核心组件来看: 服务发现:以 Eu…...
MYSQL 5.7数据库,关于1067报错 invalid default value for,解决方法!
???作者: 米罗学长 ???个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 ???各类成品java毕设 。javaweb,ssm,springboot,mysql等项目,源码丰富,欢迎咨询。 ???…...
C# Enumerable类 之 数据筛选
总目录 前言 在 C# 中,System.Linq.Enumerable 类是 LINQ(Language Integrated Query)的核心组成部分,它提供了一系列静态方法,用于操作实现了 IEnumerable 接口的集合。通过这些方法,我们可以轻松地对集合…...
运维基础知识(一)
一:SSH端口 首先SSH是什么? SSH(Secure Shell)是Linux、Unix、Mac及其他网络设备最常用的远程CLI管理协议,SSH使用秘钥对数据进行加密,保证了远程管理数据的安全性。 Secure Shell (SSH) 是一种网络协议,允许用户通过加密的通道安全地访问另一台计算机。SSH广泛用于远程…...
权重生成图像
简介 前面提到的许多生成模型都有保存了生成器的权重,本章主要介绍如何使用训练好的权重文件通过生成器生成图像。 但是如何使用权重生成图像呢? 一、参数配置 ima_size 为图像尺寸,这个需要跟你模型训练的时候resize的时候一样。 latent_dim为噪声维度,一般的设置都是…...
【Linux基础】Linux下的C编程指南
目录 一、前言 二、Vim的使用 2.1 普通模式 2.2 插入模式 2.3 命令行模式 2.4 可视模式 三、GCC编译器 3.1 预处理阶段 3.2 编译阶段 3.3 汇编阶段 3.4 链接阶段 3.5 静态库和动态库 四、Gdb调试器 五、总结 一、前言 在Linux环境下使用C语言进行编程是一项基础且…...
DeepSeek-OpenSourceWeek-第四天-Optimized Parallelism Strategies
DeepSeek 在 #OpenSourceWeek(开源周) 的第四天推出了两项新工具,旨在让深度学习更快、更高效:**DualPipe** 和 **EPLB**。 DualPipe 定义:DualPipe 是一种用于 V3/R1 训练中计算与通信重叠的双向pipline并行算法。 作用:它通过实现前向和后向计算-通信阶段的完全重叠,减…...
Python Cookbook-2.15 用类文件对象适配真实文件对象
任务 需要传递一个类似文件的对象(比如,调用urllib.urlopen 返回的结果)给一个函数或者方法,但这个函数或方法要求只接受真实的文件对象(比如,像marshalload 这样的函数)。 解决方案 为了过类型检查这一关,我们需要将类文件对象…...
浅谈HTTP及HTTPS协议
1.什么是HTTP? HTTP全称是超文本传输协议,是一种基于TCP协议的应用非常广泛的应用层协议。 1.1常见应用场景 一.浏览器与服务器之间的交互。 二.手机和服务器之间通信。 三。多个服务器之间的通信。 2.HTTP请求详解 2.1请求报文格式 我们首先看一下…...
Pytest自定义测试用例执行顺序
文章目录 1.前言2.pytest默认执行顺序3.pytest自定义执行顺序 1.前言 在pytest中,我们可能需要自定义测试用例的执行顺序,例如登陆前需要先注册,这个时候就需要先执行注册的测试用例再执行登录的测试用例。 本文主要讲解pytest的默认执行顺序…...
人大金仓KCA | 用户与角色
人大金仓KCA | 用户与角色 一、知识预备1. 用户和角色 二、具体实施1. 用户管理-命令行1.1 创建和修改用户1.2 修改用户密码1.3 修改用户的并发连接数1.4 修改用户的密码有效期 2.用户管理-EasyKStudio2.1 创建和修改用户2.2 修改用户密码2.3 修改用户的并发连接数2.4 修改用户…...
【Azure 架构师学习笔记】- Azure Databricks (12) -- Medallion Architecture简介
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (11) – UC搭建 前言 使用ADB 或者数据湖,基本上绕不开一个架构“Medallion”, 它使得数据管理更为简单有效。ADB 通过…...
什么是Ollama?什么是GGUF?二者之间有什么关系?
一、Ollama:本地化大模型运行框架 Ollama 是一款开源工具,专注于在本地环境中快速部署和运行大型语言模型(LLM)。它通过极简的命令行操作简化了模型管理流程,支持离线运行、多模型并行、私有化部署等场景。 核心特性 本地化运行:无需依赖云端API,用户可在个人电脑或服务…...
智能证件照处理器(深度学习)
功能说明:支持常见证件照尺寸(一寸、二寸、护照等) 智能背景去除(使用深度学习模型)自定义背景颜色选择自动调整尺寸并保持比例实时预览处理效果注意:整合rembg进行抠图,使用Pillow处理图像缩放和背景替换,定义常见证件照尺寸,并提供用户交互选项。首次运行时会自动下…...
【软考】【2025年系统分析师拿证之路】【啃书】第十五章 系统运行与维护(十六)
目录 运维技术指标系统运行管理系统用户管理网络资源管理软件资源管理 系统故障管理软件系统维护系统评价遗留系统处理遗留系统的评价遗留系统的演化 新旧系统转换数据转换和迁移 现有系统演进 运维技术指标 平均故障修复时间(MTTR)平均应答时间&#x…...
C++-第十三章:红黑树
目录 第一节:红黑树的特征 第二节:实现思路 2-1.插入 2-1-1.unc为红 2-1-2.cur为par的左子树,且par为gra的左子树(cur在最左边) 2-1-2-1.unc不存在 2-1-2-2.unc为黑 2-1-3.cur为par的右子树,且par为gra的右子树(cur在最右侧) 2-…...
推荐3个背景渐变色的wordpress主题
干净、清爽、背景渐变色的wordpress企业主题 服务类公司wordpress企业主题https://www.jianzhanpress.com/?p8255 红色大气的wordpress企业主题,适合服务行业的公司搭建企业官方网站使用。 wordpress询盘型独立站主题https://www.jianzhanpress.com/?p8258…...
Scrapy:隧道代理中移除 Proxy-Authorization 的原理解析
隧道代理中移除 Proxy-Authorization 的原理解析 背景 在 Scrapy 的 HTTP 下载处理中,当使用隧道代理(TunnelingAgent)时,会移除请求头中的 Proxy-Authorization。这个操作看似简单,但背后有着重要的安全考虑和技术原…...
Qt for Android下QMessageBox背景黑色、文字点击闪烁
最近在基于Qt开发安卓应用的时候,在红米平板上默认QMessageBox出现之后,背景黑色,并且点击提示文字会出现闪烁,影响用户体验。 问题分析 1、设置QMessageBox样式,设置背景色、文字颜色,如下所示: QMessageBox {background: white;color: white; } 尝试之后,问题仍存…...
Docker数据卷操作实战
什么是数据卷 数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性: 数据卷 可以在容器之间共享和享用对 数据卷 的修改立马生效对 数据卷 的更新,不会影响镜像数据卷 默认会一直存在,即时容器被…...
nginx 动态计算拦截非法访问ip
需求:在Nginx上实现一个动态拦截IP的方法,具体是当某个IP在1分钟内访问超过60次时,将其加入Redis并拦截,拦截时间默认1天。 技术选型:使用NginxLuaRedis的方法。这种方案通过Lua脚本在Nginx处理请求时检查Redis中的黑…...
微信小程序-二维码绘制
wxml <view bindlongtap"saveQrcode"><!-- 二维码 --><view style"position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id"myQrcode" style"width: 200px; height: 200px;ba…...
Node.js与MySQL的深入探讨
Node.js与MySQL的深入探讨 引言 Node.js,一个基于Chrome V8引擎的JavaScript运行时环境,以其非阻塞、事件驱动的方式在服务器端应用中占据了一席之地。MySQL,作为一款广泛使用的开源关系型数据库管理系统,凭借其稳定性和高效性,成为了许多应用的数据库选择。本文将深入探…...
【10】RUST的迭代器与闭包
文章目录 闭包(Closures)定义捕获方式:迭代器(Iterator)核心方法:创建方式:适配器(Adapter)常见适配器及示例消费方法(Consumer)所有权与引用处理性能与惰性求值闭包(Closures) 类比C++里的lambda表达式 闭包是能够捕获其所在环境变量的匿名函数,支持灵活的类型推…...
Fiddler 的安装与使用
目录 1、Fiddler 的安装2、Fiddler 的使用 1、Fiddler 的安装 通过Fiddler 官网进行下载(下载免费的经典版本),填写用途、邮箱、国家信息即可开始下载。 Fiddler 官网下载链接 双击安装包即可进行安装,显示以下界面说明安装成功。…...
Hadoop架构详解
Hadoop 是一个开源的分布式计算系统,用于存储和处理大规模数据集。Hadoop 主要由HDFS(Hadoop Distributed File System)、MapReduce、Yarn(Jobtracker,TaskTracker)三大核心组件组成。其中HDFS是分布式文件…...
清华大学DeepSeek文档下载,清华大学deepseek下载(完成版下载)
文章目录 前言一、清华大学DeepSeek使用手册下载二、清华大学DeepSeek使用手册思维导图 前言 这是一篇关于清华大学deepseek使用手册pdf的介绍性文章,主要介绍了DeepSeek的定义、功能、使用方法以及如何通过提示语设计优化AI性能。以下是对这些核心内容的简要概述&…...
