使用EdgeDB和FastAPI构建REST API教程
前言
在现代Web开发中,REST API是连接前后端的重要桥梁。本文将介绍如何利用EdgeDB这一强大的图关系数据库与FastAPI框架结合,构建一个类型安全、高效的事件管理系统API。通过本教程,您将掌握从数据库设计到API实现的完整流程。
技术栈介绍
EdgeDB
EdgeDB是一款开源的图关系数据库,它结合了关系数据库的强大功能与图数据库的灵活性。其特点包括:
- 内置类型系统
- 强大的查询语言EdgeQL
- 自动生成类型安全的客户端代码
- 原生支持异步操作
FastAPI
FastAPI是一个现代、快速(高性能)的Web框架,用于构建API,主要特点:
- 基于Python类型提示
- 自动生成交互式API文档
- 内置数据验证
- 原生支持异步
环境准备
安装必要工具
确保已安装以下组件:
- Python 3.10或更高版本
- EdgeDB命令行工具
- 创建项目目录并初始化虚拟环境:
mkdir fastapi-crud
cd fastapi-crud
python -m venv myvenv
source myvenv/bin/activate
安装依赖包
pip install edgedb fastapi httpx uvicorn
数据库初始化
创建EdgeDB项目
edgedb project init
按照提示完成项目初始化,这将创建一个新的EdgeDB实例。
验证连接
edgedb
成功连接后会显示EdgeDB交互式命令行界面。
数据模型设计
我们设计一个简单的事件管理系统,包含两个主要实体:用户(User)和事件(Event)。
基础可审计类型
首先定义一个抽象类型Auditable,用于添加创建时间戳等通用字段:
abstract type Auditable {
required created_at: datetime {
readonly := true;
default := datetime_current();
}
}
用户类型
type User extending Auditable {
required name: str {
constraint exclusive;
constraint max_len_value(50);
};
}
事件类型
type Event extending Auditable {
required name: str {
constraint exclusive;
constraint max_len_value(50);
}
address: str;
schedule: datetime;
link host: User;
}
应用迁移
edgedb migration create
edgedb migrate
API开发
项目结构
fastapi-crud/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── users.py
│ ├── events.py
│ └── queries/
│ ├── get_users.edgeql
│ ├── get_user_by_name.edgeql
│ └── create_user.edgeql
查询定义
在queries/目录下创建EdgeQL查询文件:
get_users.edgeql:
select User {name, created_at};
get_user_by_name.edgeql:
select User {name, created_at}
filter User.name = <str>$name
代码生成
edgedb-py
这将自动生成类型安全的Python查询函数。
用户API实现
users.py主要内容:
from fastapi import APIRouter, HTTPException
import edgedb
from .queries import get_users_async_edgeql as get_users_qry
from .queries import get_user_by_name_async_edgeql as get_user_by_name_qry
router = APIRouter()
client = edgedb.create_async_client()
@router.get("/users")
async def get_users(name: str = None):
if not name:
return await get_users_qry.get_users(client)
else:
user = await get_user_by_name_qry.get_user_by_name(client, name=name)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
主应用入口
main.py配置FastAPI应用:
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
from app import users
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(users.router)
启动服务
uvicorn app.main:app --reload
API测试
使用HTTP客户端测试API:
获取所有用户:
httpx GET http://localhost:8000/users
按名称查询用户:
httpx GET "http://localhost:8000/users?name=John"
进阶功能
创建用户端点
添加创建用户功能:
- 创建查询文件
create_user.edgeql:
select (insert User {
name := <str>$name
}) {
name,
created_at
};
- 重新生成代码
edgedb-py
- 实现POST端点:
@router.post("/users", status_code=201)
async def create_user(user_data: dict):
try:
return await create_user_qry.create_user(client, name=user_data["name"])
except edgedb.errors.ConstraintViolationError:
raise HTTPException(status_code=400, detail="Username already exists")
最佳实践
- 错误处理:妥善处理数据库约束错误等异常
- 输入验证:利用FastAPI的Pydantic模型进行请求验证
- 异步操作:充分利用EdgeDB和FastAPI的异步特性
- 类型安全:始终使用生成的类型进行注解
- API文档:FastAPI会自动生成OpenAPI文档,访问
/docs查看
总结
通过本教程,我们完成了:
- EdgeDB数据库的初始化和建模
- 使用EdgeQL定义查询并生成类型安全的Python代码
- 使用FastAPI构建RESTful端点
- 实现基本的CRUD操作
这种技术组合提供了出色的开发体验和运行时性能,特别适合需要复杂数据关系和强类型保证的应用场景。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



