使用Python和Flask构建一个简单的REST API

发布于 / 技术文章 / 0条评论 / Tags: none / 112 次浏览

实战教程:使用Python和Flask构建一个简单的REST API

Python and Flask Logos

前言

在现代的Web和移动应用开发中,REST API (Representational State Transfer Application Programming Interface) 扮演着至关重要的角色。它是一种架构风格,定义了一组用于创建网络服务的约束。通过API,不同的应用程序(例如,一个前端网站和一个后端服务器)可以相互通信。

Python拥有众多优秀的Web框架,其中 Flask 以其轻量、灵活和易于上手的特点,成为构建API和Web应用的热门选择。 [6]

本教程将手把手带你使用Python和Flask,从零开始构建一个简单的书店REST API。你将学会如何处理不同的HTTP请求(GET, POST, PUT, DELETE),并创建一个功能完备的CRUD(创建、读取、更新、删除)服务。

准备工作

在开始之前,请确保你的电脑上已经安装了以下软件:

  • Python 3: 你可以从 Python官网 下载并安装。
  • 代码编辑器: 例如 VS Code, Sublime Text, 或者 PyCharm。
  • 命令行工具: 如 Windows的CMD/PowerShell 或 macOS/Linux的Terminal。
  • (可选) API测试工具: 如 Postman 或 Insomnia。我们也会提供使用 curl 的命令行测试方法。

第一步:搭建项目环境

一个良好的项目结构和隔离的开发环境是成功的开始。

  1. 创建项目文件夹
    打开你的命令行工具,创建一个新的项目文件夹并进入该目录。

    mkdir flask-book-api
    cd flask-book-api
  2. 创建并激活虚拟环境
    使用虚拟环境可以确保项目的依赖与全局Python环境隔离,避免版本冲突。

    # For macOS/Linux
    python3 -m venv venv
    source venv/bin/activate
    
    # For Windows
    python -m venv venv
    .\venv\Scripts\activate

    激活成功后,你会在命令行提示符前看到 (venv) 的字样。

  3. 安装Flask
    在激活的虚拟环境中,使用pip安装Flask。

    pip install Flask

第二步:你的第一个Flask应用

让我们从一个经典的 "Hello, World!" 开始,以确保Flask已经正确安装。

  1. flask-book-api 文件夹中,创建一个名为 app.py 的文件。
  2. app.py 中输入以下代码:

    from flask import Flask
    
    # 创建一个Flask应用实例
    app = Flask(__name__)
    
    # 定义一个路由和视图函数
    @app.route('/')
    def hello_world():
        return 'Hello, World!'
    
    # 确保直接运行时才启动服务器
    if __name__ == '__main__':
        app.run(debug=True)
    • app = Flask(__name__):创建了Flask应用的一个实例。
    • @app.route('/'):这是一个装饰器,它告诉Flask哪个URL应该触发我们的函数。/ 是网站的根路径。
    • app.run(debug=True):启动开发服务器。debug=True 会在代码修改后自动重启服务器,并提供详细的错误信息。
  3. 运行应用
    在命令行中运行以下命令:

    python app.py

    你应该会看到类似以下的输出:

     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
     * ...

    现在,打开浏览器并访问 http://127.0.0.1:5000/,你将看到 "Hello, World!" 的字样。

第三步:设计我们的REST API

我们的书店API需要处理关于“书籍”的资源。我们将定义以下几个API端点(Endpoints)来操作书籍数据。为了简化,我们暂时将数据存储在内存的一个列表中。

HTTP 方法URL 端点动作
GET/books获取所有书籍的列表
GET/books/<int:book_id>获取指定ID的书籍信息
POST/books添加一本新书
PUT/books/<int:book_id>更新指定ID的书籍信息
DELETE/books/<int:book_id>删除指定ID的书籍

第四步:实现API功能

现在,让我们来修改 app.py 文件,实现完整的CRUD功能。

用以下代码替换 app.py 的全部内容:

from flask import Flask, jsonify, request

app = Flask(__name__)

# 使用内存数据库(一个字典列表)
books = [
    {'id': 1, 'title': 'The Lord of the Rings', 'author': 'J.R.R. Tolkien'},
    {'id': 2, 'title': 'Pride and Prejudice', 'author': 'Jane Austen'}
]
next_book_id = 3

# GET /books - 获取所有书籍
@app.route('/books', methods=['GET'])
def get_books():
    return jsonify({'books': books})

# GET /books/<id> - 获取指定书籍
@app.route('/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
    book = next((book for book in books if book['id'] == book_id), None)
    if book:
        return jsonify({'book': book})
    return jsonify({'message': 'Book not found'}), 404

# POST /books - 添加新书
@app.route('/books', methods=['POST'])
def add_book():
    global next_book_id
    if not request.json or not 'title' in request.json or not 'author' in request.json:
        return jsonify({'message': 'Bad request, title and author are required'}), 400
    
    new_book = {
        'id': next_book_id,
        'title': request.json['title'],
        'author': request.json['author']
    }
    books.append(new_book)
    next_book_id += 1
    return jsonify({'book': new_book}), 201

# PUT /books/<id> - 更新书籍信息
@app.route('/books/<int:book_id>', methods=['PUT'])
def update_book(book_id):
    book = next((book for book in books if book['id'] == book_id), None)
    if not book:
        return jsonify({'message': 'Book not found'}), 404
    
    if not request.json:
        return jsonify({'message': 'Bad request'}), 400

    book['title'] = request.json.get('title', book['title'])
    book['author'] = request.json.get('author', book['author'])
    return jsonify({'book': book})

# DELETE /books/<id> - 删除书籍
@app.route('/books/<int:book_id>', methods=['DELETE'])
def delete_book(book_id):
    global books
    book = next((book for book in books if book['id'] == book_id), None)
    if not book:
        return jsonify({'message': 'Book not found'}), 404
    
    books = [b for b in books if b['id'] != book_id]
    return jsonify({'message': 'Book deleted successfully'})

if __name__ == '__main__':
    app.run(debug=True)

代码解释:

  • jsonify: 这是一个Flask函数,可以将Python字典转换为JSON格式的响应,并自动设置正确的 Content-Type 头 (application/json)。 [7]
  • request: 从 flask 导入,用于访问传入的请求数据,例如 request.json 可以获取POST或PUT请求中的JSON数据。 [10]
  • methods=['GET', 'POST']: 默认情况下,路由只响应GET请求。要处理其他HTTP方法,需要在 @app.route() 装饰器中指定。 [11]
  • 状态码: 我们返回了不同的HTTP状态码来表示请求的结果,如 201 Created 表示资源创建成功,404 Not Found 表示资源未找到。

第五步:测试你的API

确保你的 app.py 仍在运行。现在,打开一个新的命令行窗口(不要关闭正在运行Flask的那个),我们将使用 curl 来测试我们的API。

  1. 获取所有书籍 (GET)

    curl http://127.0.0.1:5000/books

    响应:

    {
      "books": [
        {
          "author": "J.R.R. Tolkien", 
          "id": 1, 
          "title": "The Lord of the Rings"
        }, 
        {
          "author": "Jane Austen", 
          "id": 2, 
          "title": "Pride and Prejudice"
        }
      ]
    }
  2. 添加一本新书 (POST)

    curl -X POST -H "Content-Type: application/json" -d '{"title": "1984", "author": "George Orwell"}' http://127.0.0.1:5000/books

    响应:

    {
      "book": {
        "author": "George Orwell", 
        "id": 3, 
        "title": "1984"
      }
    }
  3. 获取指定ID的书籍 (GET)

    curl http://127.0.0.1:5000/books/3

    响应:

    {
      "book": {
        "author": "George Orwell", 
        "id": 3, 
        "title": "1984"
      }
    }
  4. 更新书籍信息 (PUT)

    curl -X PUT -H "Content-Type: application/json" -d '{"title": "Nineteen Eighty-Four"}' http://127.0.0.1:5000/books/3

    响应:

    {
      "book": {
        "author": "George Orwell", 
        "id": 3, 
        "title": "Nineteen Eighty-Four"
      }
    }
  5. 删除书籍 (DELETE)

    curl -X DELETE http://127.0.0.1:5000/books/3

    响应:

    {
      "message": "Book deleted successfully"
    }

总结

恭喜你!你已经成功使用Python和Flask构建并测试了一个功能完整的REST API。

在本教程中,你学习了:

  • 如何设置一个基本的Flask项目。
  • 如何定义路由并处理不同的HTTP方法。
  • 如何使用 jsonify 返回JSON数据。
  • 如何使用 request 处理传入的JSON数据。
  • 如何实现一个完整的CRUD(创建、读取、更新、删除)服务。

这只是一个开始。从这里出发,你可以继续探索更高级的主题,例如:

  • 数据库集成: 用SQLite, PostgreSQL等真实数据库替换内存数据。
  • 数据校验: 使用 Marshmallow 等库来验证和序列化数据。
  • 认证与授权: 添加用户登录和权限控制。
  • 蓝图 (Blueprints): 组织更大型的Flask应用。

希望本教程能为你的Web开发之旅提供一个坚实的起点!

    评论区(暂无评论)