从零开始:利用 Flask 或 Django 构建 RESTful API

守听  金牌会员 | 2024-10-19 13:40:31 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 882|帖子 882|积分 2646

引言

在当今这个数据驱动的时代,构建高效、可扩展的后端服务变得尤为紧张。RESTful API 作为一种设计模式,已经成为今世 Web 开发的标准之一。无论是小型初创公司还是大型企业,都需要一个强大的后端来支持前端应用的快速迭代和用户需求的变革。Flask 和 Django 是 Python 生态中最受欢迎的两个 Web 框架,它们都可以用来构建 RESTful API。本文将具体介绍如何利用这两个框架来构建 RESTful API,并通过实例帮助你理解其核心概念和实际应用。
基础语法介绍

什么是 RESTful API?

REST(Representational State Transfer)是一种软件架构风格,它定义了一组束缚条件和架构原则。RESTful API 是基于这些原则设计的 Web 服务接口,通常利用 HTTP 协议进行通信。RESTful API 的核心特性包罗:


  • 无状态性:每个请求都必须包罗所有必要的信息,服务器不会生存任何会话状态。
  • 统一接口:利用标准的 HTTP 方法(GET、POST、PUT、DELETE 等)来操纵资源。
  • 资源导向:API 的 URL 应该指向资源,而不是操纵。
Flask vs Django

Flask

Flask 是一个轻量级的 Web 框架,非常适合快速开发和小型项目。它的核心非常简单,但可以通过扩展来添加更多功能。Flask 的机动性使得它可以适应各种差异的应用场景。
Django

Django 是一个全栈框架,提供了丰富的功能和工具,适合大型项目和企业级应用。Django 内置了 ORM、认证体系、管理后台等,可以大大减少开发时间和工作量。
核心概念



  • 路由:定义 URL 与视图函数之间的映射关系。
  • 视图:处置惩罚请求并返回相应。
  • 模子:表现数据库中的数据布局。
  • 序列化器:将模子对象转换为 JSON 格式,以便通过 API 返回。
基础实例

利用 Flask 构建 RESTful API

问题描述

假设我们需要构建一个简单的 API 来管理用户的个人信息。用户可以创建、读取、更新和删除自己的信息。
代码示例

首先,安装 Flask 和 Flask-RESTful:
  1. pip install Flask Flask-RESTful
复制代码
然后,创建一个简单的 Flask 应用:
  1. from flask import Flask, request
  2. from flask_restful import Resource, Api
  3. app = Flask(__name__)
  4. api = Api(app)
  5. # 模拟数据库
  6. users = {}
  7. class UserResource(Resource):
  8.     def get(self, user_id):
  9.         if user_id in users:
  10.             return users[user_id], 200
  11.         else:
  12.             return {"message": "User not found"}, 404
  13.     def post(self, user_id):
  14.         if user_id in users:
  15.             return {"message": "User already exists"}, 400
  16.         else:
  17.             data = request.get_json()
  18.             users[user_id] = data
  19.             return data, 201
  20.     def put(self, user_id):
  21.         if user_id in users:
  22.             data = request.get_json()
  23.             users[user_id].update(data)
  24.             return users[user_id], 200
  25.         else:
  26.             return {"message": "User not found"}, 404
  27.     def delete(self, user_id):
  28.         if user_id in users:
  29.             del users[user_id]
  30.             return {"message": "User deleted"}, 200
  31.         else:
  32.             return {"message": "User not found"}, 404
  33. api.add_resource(UserResource, '/users/<string:user_id>')
  34. if __name__ == '__main__':
  35.     app.run(debug=True)
复制代码
利用 Django 构建 RESTful API

问题描述

同样的场景,我们利用 Django 来构建一个用户管理的 API。
代码示例

首先,安装 Django 和 Django REST framework:
  1. pip install Django djangorestframework
复制代码
然后,创建一个新的 Django 项目和应用:
  1. django-admin startproject myproject
  2. cd myproject
  3. python manage.py startapp myapp
复制代码
编辑 myapp/models.py 文件,定义用户模子:
  1. from django.db import models
  2. class User(models.Model):
  3.     name = models.CharField(max_length=100)
  4.     email = models.EmailField(unique=True)
  5.     def __str__(self):
  6.         return self.name
复制代码
编辑 myapp/serializers.py 文件,定义序列化器:
  1. from rest_framework import serializers
  2. from .models import User
  3. class UserSerializer(serializers.ModelSerializer):
  4.     class Meta:
  5.         model = User
  6.         fields = ['id', 'name', 'email']
复制代码
编辑 myapp/views.py 文件,定义视图:
  1. from rest_framework import viewsets
  2. from .models import User
  3. from .serializers import UserSerializer
  4. class UserViewSet(viewsets.ModelViewSet):
  5.     queryset = User.objects.all()
  6.     serializer_class = UserSerializer
复制代码
编辑 myapp/urls.py 文件,定义路由:
  1. from django.urls import path, include
  2. from rest_framework.routers import DefaultRouter
  3. from .views import UserViewSet
  4. router = DefaultRouter()
  5. router.register(r'users', UserViewSet)
  6. urlpatterns = [
  7.     path('', include(router.urls)),
  8. ]
复制代码
最后,编辑 myproject/urls.py 文件,包罗应用的路由:
  1. from django.contrib import admin
  2. from django.urls import path, include
  3. urlpatterns = [
  4.     path('admin/', admin.site.urls),
  5.     path('api/', include('myapp.urls')),
  6. ]
复制代码
运行迁移下令以创建数据库表:
  1. python manage.py migrate
复制代码
启动 Django 开发服务器:
  1. python manage.py runserver
复制代码
现在,你可以通过访问 http://127.0.0.1:8000/api/users/ 来测试 API。
进阶实例

利用 Flask 构建复杂的 RESTful API

问题描述

假设我们需要构建一个更复杂的 API,支持分页、过滤和排序功能。
高级代码实例

首先,安装 Flask-SQLAlchemy 和 Flask-Marshmallow:
  1. pip install Flask-SQLAlchemy Flask-Marshmallow marshmallow-sqlalchemy
复制代码
然后,创建一个 Flask 应用:
  1. from flask import Flask, request, jsonify
  2. from flask_sqlalchemy import SQLAlchemy
  3. from flask_marshmallow import Marshmallow
  4. app = Flask(__name__)
  5. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
  6. db = SQLAlchemy(app)
  7. ma = Marshmallow(app)
  8. # 定义用户模型
  9. class User(db.Model):
  10.     id = db.Column(db.Integer, primary_key=True)
  11.     name = db.Column(db.String(100))
  12.     email = db.Column(db.String(100), unique=True)
  13. # 定义序列化器
  14. class UserSchema(ma.SQLAlchemyAutoSchema):
  15.     class Meta:
  16.         model = User
  17. user_schema = UserSchema()
  18. users_schema = UserSchema(many=True)
  19. @app.route('/users', methods=['GET'])
  20. def get_users():
  21.     query = User.query
  22.     name = request.args.get('name')
  23.     if name:
  24.         query = query.filter(User.name.contains(name))
  25.    
  26.     sort_by = request.args.get('sort_by', 'name')
  27.     sort_order = request.args.get('sort_order', 'asc')
  28.     if sort_order == 'desc':
  29.         query = query.order_by(getattr(User, sort_by).desc())
  30.     else:
  31.         query = query.order_by(getattr(User, sort_by))
  32.     page = request.args.get('page', 1, type=int)
  33.     per_page = request.args.get('per_page', 10, type=int)
  34.     paginated_users = query.paginate(page, per_page, error_out=False)
  35.     return users_schema.jsonify(paginated_users.items)
  36. @app.route('/users', methods=['POST'])
  37. def create_user():
  38.     data = request.get_json()
  39.     new_user = User(name=data['name'], email=data['email'])
  40.     db.session.add(new_user)
  41.     db.session.commit()
  42.     return user_schema.jsonify(new_user), 201
  43. @app.route('/users/<int:user_id>', methods=['PUT'])
  44. def update_user(user_id):
  45.     user = User.query.get_or_404(user_id)
  46.     data = request.get_json()
  47.     user.name = data.get('name', user.name)
  48.     user.email = data.get('email', user.email)
  49.     db.session.commit()
  50.     return user_schema.jsonify(user)
  51. @app.route('/users/<int:user_id>', methods=['DELETE'])
  52. def delete_user(user_id):
  53.     user = User.query.get_or_404(user_id)
  54.     db.session.delete(user)
  55.     db.session.commit()
  56.     return '', 204
  57. if __name__ == '__main__':
  58.     db.create_all()
  59.     app.run(debug=True)
复制代码
利用 Django 构建复杂的 RESTful API

问题描述

同样的场景,我们利用 Django 来构建一个支持分页、过滤和排序的 API。
高级代码实例

首先,安装 Django-Filter:
  1. pip install django-filter
复制代码
然后,编辑 myapp/filters.py 文件,定义过滤器:
  1. import django_filters
  2. from .models import User
  3. class UserFilter(django_filters.FilterSet):
  4.     name = django_filters.CharFilter(lookup_expr='icontains')
  5.     class Meta:
  6.         model = User
  7.         fields = ['name', 'email']
复制代码
编辑 myapp/views.py 文件,定义视图:
  1. from rest_framework import filters
  2. from .models import User
  3. from .serializers import UserSerializer
  4. from .filters import UserFilter
  5. class UserViewSet(viewsets.ModelViewSet):
  6.     queryset = User.objects.all()
  7.     serializer_class = UserSerializer
  8.     filter_backends = [filters.SearchFilter, filters.OrderingFilter, django_filters.rest_framework.DjangoFilterBackend]
  9.     filterset_class = UserFilter
  10.     search_fields = ['name', 'email']
  11.     ordering_fields = ['name', 'email']
复制代码
现在,你可以通过访问 http://127.0.0.1:8000/api/users/?name=John&sort_by=name&sort_order=desc&page=1&per_page=10 来测试 API。
实战案例

项目配景

假设你在一个电商平台上工作,需要构建一个 API 来管理商品信息。商品信息包罗名称、描述、代价、库存等。你需要支持商品的增删改查操纵,而且提供分页、过滤和排序功能。
问题描述



  • 商品信息需要存储在数据库中。
  • API 需要支持分页、过滤和排序功能。
  • 需要处置惩罚并发请求,包管数据的一致性。
解决方案

利用 Flask 构建 API


  • 模子定义:定义商品模子,利用 SQLAlchemy 作为 ORM。
  • 序列化器:利用 Flask-Marshmallow 将模子对象转换为 JSON 格式。
  • 视图函数:定义处置惩罚请求的视图函数,支持分页、过滤和排序。
  • 并发处置惩罚:利用 Flask-SQLAlchemy 的事件管理功能,包管数据的一致性。
代码实现

  1. from flask import Flask, request, jsonify
  2. from flask_sqlalchemy import SQLAlchemy
  3. from flask_marshmallow import Marshmallow
  4. app = Flask(__name__)
  5. app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///products.db'
  6. db = SQLAlchemy(app)
  7. ma = Marshmallow(app)
  8. # 定义商品模型
  9. class Product(db.Model):
  10.     id = db.Column(db.Integer, primary_key=True)
  11.     name = db.Column(db.String(100))
  12.     description = db.Column(db.String(500))
  13.     price = db.Column(db.Float)
  14.     stock = db.Column(db.Integer)
  15. # 定义序列化器
  16. class ProductSchema(ma.SQLAlchemyAutoSchema):
  17.     class Meta:
  18.         model = Product
  19. product_schema = ProductSchema()
  20. products_schema = ProductSchema(many=True)
  21. @app.route('/products', methods=['GET'])
  22. def get_products():
  23.     query = Product.query
  24.     name = request.args.get('name')
  25.     if name:
  26.         query = query.filter(Product.name.contains(name))
  27.    
  28.     sort_by = request.args.get('sort_by', 'name')
  29.     sort_order = request.args.get('sort_order', 'asc')
  30.     if sort_order == 'desc':
  31.         query = query.order_by(getattr(Product, sort_by).desc())
  32.     else:
  33.         query = query.order_by(getattr(Product, sort_by))
  34.     page = request.args.get('page', 1, type=int)
  35.     per_page = request.args.get('per_page', 10, type=int)
  36.     paginated_products = query.paginate(page, per_page, error_out=False)
  37.     return products_schema.jsonify(paginated_products.items)
  38. @app.route('/products', methods=['POST'])
  39. def create_product():
  40.     data = request.get_json()
  41.     new_product = Product(name=data['name'], description=data['description'], price=data['price'], stock=data['stock'])
  42.     db.session.add(new_product)
  43.     db.session.commit()
  44.     return product_schema.jsonify(new_product), 201
  45. @app.route('/products/<int:product_id>', methods=['PUT'])
  46. def update_product(product_id):
  47.     product = Product.query.get_or_404(product_id)
  48.     data = request.get_json()
  49.     product.name = data.get('name', product.name)
  50.     product.description = data.get('description', product.description)
  51.     product.price = data.get('price', product.price)
  52.     product.stock = data.get('stock', product.stock)
  53.     db.session.commit()
  54.     return product_schema.jsonify(product)
  55. @app.route('/products/<int:product_id>', methods=['DELETE'])
  56. def delete_product(product_id):
  57.     product = Product.query.get_or_404(product_id)
  58.     db.session.delete(product)
  59.     db.session.commit()
  60.     return '', 204
  61. if __name__ == '__main__':
  62.     db.create_all()
  63.     app.run(debug=True)
复制代码
利用 Django 构建 API


  • 模子定义:定义商品模子,利用 Django 的 ORM。
  • 序列化器:利用 Django REST framework 将模子对象转换为 JSON 格式。
  • 视图集:定义处置惩罚请求的视图集,支持分页、过滤和排序。
  • 并发处置惩罚:利用 Django 的事件管理功能,包管数据的一致性。
代码实现

编辑 myapp/models.py 文件,定义商品模子:
  1. from django.db import models
  2. class Product(models.Model):
  3.     name = models.CharField(max_length=100)
  4.     description = models.TextField()
  5.     price = models.DecimalField(max_digits=10, decimal_places=2)
  6.     stock = models.IntegerField()
  7.     def __str__(self):
  8.         return self.name
复制代码
编辑 myapp/serializers.py 文件,定义序列化器:
  1. from rest_framework import serializers
  2. from .models import Product
  3. class ProductSerializer(serializers.ModelSerializer):
  4.     class Meta:
  5.         model = Product
  6.         fields = ['id', 'name', 'description', 'price', 'stock']
复制代码
编辑 myapp/filters.py 文件,定义过滤器:
  1. import django_filters
  2. from .models import Product
  3. class ProductFilter(django_filters.FilterSet):
  4.     name = django_filters.CharFilter(lookup_expr='icontains')
  5.     class Meta:
  6.         model = Product
  7.         fields = ['name', 'price', 'stock']
复制代码
编辑 myapp/views.py 文件,定义视图集:
  1. from rest_framework import filters
  2. from .models import Product
  3. from .serializers import ProductSerializer
  4. from .filters import ProductFilter
  5. class ProductViewSet(viewsets.ModelViewSet):
  6.     queryset = Product.objects.all()
  7.     serializer_class = ProductSerializer
  8.     filter_backends = [filters.SearchFilter, filters.OrderingFilter, django_filters.rest_framework.DjangoFilterBackend]
  9.     filterset_class = ProductFilter
  10.     search_fields = ['name', 'description']
  11.     ordering_fields = ['name', 'price', 'stock']
复制代码
编辑 myapp/urls.py 文件,定义路由:
  1. from django.urls import path, include
  2. from rest_framework.routers import DefaultRouter
  3. from .views import ProductViewSet
  4. router = DefaultRouter()
  5. router.register(r'products', ProductViewSet)
  6. urlpatterns = [
  7.     path('', include(router.urls)),
  8. ]
复制代码
编辑 myproject/urls.py 文件,包罗应用的路由:
  1. from django.contrib import admin
  2. from django.urls import path, include
  3. urlpatterns = [
  4.     path('admin/', admin.site.urls),
  5.     path('api/', include('myapp.urls')),
  6. ]
复制代码
运行迁移下令以创建数据库表:
  1. python manage.py migrate
复制代码
启动 Django 开发服务器:
  1. python manage.py runserver
复制代码
现在,你可以通过访问 http://127.0.0.1:8000/api/products/?name=Apple&sort_by=price&sort_order=desc&page=1&per_page=10 来测试 API。
扩展讨论

性能优化



  • 缓存:利用缓存技术(如 Redis)来减少数据库查询次数,提高相应速度。
  • 异步处置惩罚:利用异步任务队列(如 Celery)来处置惩罚耗时的任务,如发送邮件、天生报表等。
  • 负载均衡:利用负载均衡器(如 Nginx)来分散请求,提高体系的可用性和性能。
安全性



  • 身份验证:利用 JWT 或 OAuth2 进行身份验证,确保只有授权用户才能访问敏感数据。
  • 输入验证:对用户输入进行严格的验证,防止 SQL 注入、XSS 攻击等安全漏洞。
  • 日志记载:记载关键操纵的日志,便于问题排查和审计。
部署与运维



  • 容器化:利用 Docker 容器化应用,简化部署和运维。
  • 持续集成/持续部署:利用 CI/CD 工具(如 Jenkins、GitHub Actions)自动化测试和部署流程。
  • 监控与报警:利用监控工具(如 Prometheus、Grafana)实时监控应用的状态,实时发现和解决问题。
社区与资源



  • 官方文档:Flask 和 Django 的官方文档黑白常好的学习资源,发起深入阅读。
  • 社区论坛:Stack Overflow、Reddit 等社区有很多开发者分享履历和解决问题的方法。
  • 开源项目:GitHub 上有很多良好的开源项目,可以参考和学习。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

守听

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表