用 Flask 来写个轻博客 (36) — 使用 Flask-RESTful 来构建 RESTful API 之五

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 目录目录前文列表PUT 请求DELETE 请求测试对一条已经存在的 posts 记录进行 update 操作删除一条记录前文列表用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hel...

目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目
用 Flask 来写个轻博客 (2) — Hello World!
用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy
用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表
用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解
用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)
用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级
用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览
用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法
用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数
用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单
用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图
用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目
用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象
用 Flask 来写个轻博客 (19) — 以 Bcrypt 密文存储账户信息与实现用户登陆表单
用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码
用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录
用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面
用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录
用 Flask 来写个轻博客 (24) — 使用 Flask-Login 来保护应用安全
用 Flask 来写个轻博客 (25) — 使用 Flask-Principal 实现角色权限功能
用 Flask 来写个轻博客 (26) — 使用 Flask-Celery-Helper 实现异步任务
用 Flask 来写个轻博客 (27) — 使用 Flask-Cache 实现网页缓存加速
用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy
用 Flask 来写个轻博客 (30) — 使用 Flask-Admin 增强文章管理功能
用 Flask 来写个轻博客 (31) — 使用 Flask-Admin 实现 FileSystem 管理
用 Flask 来写个轻博客 (32) — 使用 Flask-RESTful 来构建 RESTful API 之一
用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二
用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三
用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四

PUT 请求

紧接前 4 篇, 继续完成 PUT 和 DELETE 请求的实现.

  • PUT 请求对应的是资源类的 put() 方法, 表示更新操作. 所以仍然需要先定义 post_put 解析器
    vim jmilkfansblog/controllers/flask_restful/parsers.py
post_put_parser = reqparse.RequestParser()

post_put_parser.add_argument(
    'title',
    type=str)

post_put_parser.add_argument(
    'text',
    type=str)

post_put_parser.add_argument(
    'tags',
    type=str,
    action='append')

post_put_parser.add_argument(
    'token',
    type=str,
    required=True,
    help='Auth Token is required to update the posts.')

NOTE: 从 post_put_parser 解析器可以看见, 我们仅允许传入最多 4 个参数, 其中也一定不能缺少 token 以保证数据的安全性.

  • 定义资源类 PostApi 的 put() 更新方法
    vim jmilkfansblog/controllers/flask_restful/posts.py
...

    def put(self, post_id=None):
        """Will be execute when receive the HTTP Request Methos `PUT`."""

        if not post_id:
            abort(400)

        post = Post.query.filter_by(id=post_id).first()
        if not post:
            abort(404)

        args = parsers.post_put_parser.parse_args()
        user = User.verify_auth_token(args['token'])

        if not user:
            abort(401)
        if user != post.user:
            abort(403)

        if args['title']:
            post.title = args['title']
        if args['text']:
            post.text = args['text']
        if args['tags']:
            for item in args['tags']:
                tag = Tag.query.filter_by(name=item).first()
                if tag:
                    post.tags.append(tag)
                else:
                   new_tag = Tag()
                   new_tag.name = item
                   post.tags.append(new_tag)

        db.session.add(post)
        db.session.commit()

        return (post.id, 201)
...

NOTE: put() 方法和 post() 方法很相似, 所以这里不在赘叙.

DELETE 请求

DELETE 请求的实现是最简单的, 一般而言, 不需要返回任何的数据, 只需要返回正确的 HTTP status_int 就可以了.
vim jmilkfansblog/controllers/flask_restful/posts.py

    def delete(self, post_id=None):
        """Will be execute when receive the HTTP Request Method `DELETE`."""

        if not post_id:
            abort(400)

        post = Post.query.filter_by(id=post_id).first()
        if not post:
            abort(404)

        args = parsers.post_delete_parser.parse_args(strict=True)
        user = User.verify_auth_token(args['token'])
        if user != post.user:
            abort(403)

        # Will be delete relationship record with posts_tags too.
        # But you have to ensure the number of record equal with len(post.tags)
        db.session.delete(post)
        db.session.commit()

        return "", 204

测试

对一条已经存在的 posts 记录进行 update 操作

mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
| id                                   | title     | text  | publish_date | user_id                              |
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
| 1746b650-bcab-436b-82ab-7411e252b576 | Just Test | Hello | NULL         | 65cb9792-b876-49e7-b2c5-46468624199e |
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
1 row in set (0.00 sec)
  • 获取 Token
jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -d "username=<username>" -d "password=<password>" http://localhost:8089/api/auth
{
    "token": "eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjExNywiaWF0IjoxNDgzMzYxNTE3fQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.2r7f-SZJS2U8Zafqyl7oUYPfFGilDJemVwImPuIHxd0"
}
  • PUT 请求
jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -X PUT -d "title=Just Test PUT" -d "text=Hello Guys" -d "tags=Python" -d "tags=Flask" -d "token=eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjExNywiaWF0IjoxNDgzMzYxNTE3fQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.2r7f-SZJS2U8Zafqyl7oUYPfFGilDJemVwImPuIHxd0" http://localhost:8089/api/posts/1746b650-bcab-436b-82ab-7411e252b576
"1746b650-bcab-436b-82ab-7411e252b576"
  • 结果
mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
| id                                   | title         | text       | publish_date | user_id                              |
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
| 1746b650-bcab-436b-82ab-7411e252b576 | Just Test PUT | Hello Guys | NULL         | 65cb9792-b876-49e7-b2c5-46468624199e |
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
1 row in set (0.00 sec)

删除一条记录

jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -X DELETE -d "token=eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjkzMywiaWF0IjoxNDgzMzYyMzMzfQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.B8ISY5Fb6AD_PyrJxNVQNYuxXUMrEioB-rlhtyvYcxU" http://localhost:8089/api/posts/1746b650-bcab-436b-82ab-7411e252b576
  • 结果
mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
Empty set (0.00 sec)
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
缓存 测试技术 API
RESTful API的最佳实践
【5月更文挑战第11天】在Python中构建RESTful API时,可以选择轻量级的Flask或全栈的Django框架。Flask适用于小型到中型API,而Django适合大型复杂项目。示例代码展示了如何在两个框架中创建任务列表API。
5 0
|
5天前
|
存储 缓存 JavaScript
深入理解RESTful API设计原则与实践
【5月更文挑战第7天】在现代Web服务开发中,表述性状态传递(REST)是一种广泛采用的架构风格,用于构建可扩展的网络应用程序接口(APIs)。本文将探讨RESTful API的核心设计原则,并通过具体实例展示如何实现一个符合REST约束的后端服务。我们将讨论资源的识别、客户端-服务器通信模式、无状态性、以及统一接口的重要性,并探索如何使用当前的流行技术栈来实现这些概念。
|
12天前
|
缓存 监控 JavaScript
Node.js中构建RESTful API的最佳实践
【4月更文挑战第30天】本文介绍了在Node.js中构建RESTful API的最佳实践:选择合适的框架(如Express、Koa)、设计清晰的API接口(遵循HTTP动词和资源路径)、实现认证授权(JWT、OAuth 2.0)、错误处理、限流缓存、编写文档和测试,以及监控性能优化。这些实践有助于创建健壮、可维护和易用的API。
|
12天前
|
存储 关系型数据库 Go
【Go语言专栏】基于Go语言的RESTful API开发
【4月更文挑战第30天】本文介绍了使用Go语言开发RESTful API的方法,涵盖了路由、请求处理、数据存储和测试关键点。RESTful API基于HTTP协议,无状态且使用标准方法表示操作。在Go中,通过第三方库如`gorilla/mux`进行路由映射,使用`net/http`处理请求,与数据库交互可选ORM库`gorm`,测试则依赖于Go内置的`testing`框架。Go的简洁性和并发性使得它成为构建高效API的理想选择。
|
13天前
|
缓存 监控 API
|
20天前
|
缓存 JSON 负载均衡
构建高效RESTful API的最佳实践
【4月更文挑战第22天】在当今互联网应用的开发中,后端系统的核心通常体现在API的设计和实现上。一个设计良好、性能优异的RESTful API能够极大地提升应用的响应速度及用户体验。本文将探讨在构建高效RESTful API时应当遵循的一系列最佳实践,包括合理的数据结构设计、缓存策略、负载均衡技术以及API版本管理等。通过这些实践,可以确保API服务的高性能与易维护性,并适应不断变化的业务需求。
|
28天前
|
缓存 负载均衡 NoSQL
构建高效可扩展的RESTful API:后端开发的最佳实践
【4月更文挑战第14天】在当今快速发展的网络应用时代,一个结构良好且高效的RESTful API是确保后端服务可靠性和性能的关键。本文深入探讨了设计和实现高效可扩展RESTful API的最佳实践,涵盖了API设计原则、数据库优化、缓存策略以及负载均衡等关键方面。文中不仅提供了具体的技术建议,还通过案例分析展示了如何应对实际开发中的挑战。
|
1月前
|
缓存 安全 API
构建高效RESTful API的最佳实践
【4月更文挑战第4天】 随着移动和Web应用的兴起,RESTful API已成为前后端交互的重要桥梁。本文将深入探讨如何构建一个既符合REST原则又具有高性能的API服务。我们将从API设计原则出发,讨论资源划分、HTTP方法使用、状态码表达、缓存策略、版本控制及安全措施等关键方面。同时,将提供实用的编码技巧和工具选择建议,帮助开发者提升API的性能和可维护性。
|
2月前
|
缓存 前端开发 API
构建高效可扩展的RESTful API:后端开发的最佳实践
【2月更文挑战第30天】 在现代Web应用和服务端架构中,RESTful API已成为连接前端与后端、实现服务间通信的重要接口。本文将探讨构建一个高效且可扩展的RESTful API的关键步骤和最佳实践,包括设计原则、性能优化、安全性考虑以及错误处理机制。通过这些实践,开发者可以确保API的健壮性、易用性和未来的可维护性。
|
2月前
|
API 开发者 UED
深入探讨RESTful API设计原则及最佳实践
在当今互联网时代,RESTful API已成为各种软件系统之间进行通信的重要方式。本文将从资源定义、URI设计、HTTP方法选择、状态码规范等方面深入探讨RESTful API设计的原则与最佳实践,帮助开发者更好地构建高效、健壮的API。