分享

MoeFocalors' Blog

FastAPI Engagement API需求

🎯 FastAPI Engagement API 需求文档

本文档详细说明了Paimon1999主题所需的访问计数和点赞API接口规范。

📋 API 端点规范

1. 访问计数 (Views) API

POST /api/views/{post_id}

功能:记录文章访问计数

  • 方法:POST
  • 路径参数
    • post_id: 文章ID (如 “2025/12/27/undefined-1/“)
  • 请求头
    • Content-Type: application/json
  • 响应
    1
    2
    3
    {
    "views": 123
    }
  • 状态码
    • 200: 成功
    • 404: 文章不存在
    • 500: 服务器错误

GET /api/views/{post_id}

功能:获取文章访问计数

  • 方法:GET
  • 路径参数
    • post_id: 文章ID
  • 响应
    1
    2
    3
    {
    "views": 123
    }
  • 状态码
    • 200: 成功
    • 404: 文章不存在

2. 点赞 (Likes) API

POST /api/likes/{post_id}

功能:给文章点赞

  • 方法:POST
  • 路径参数
    • post_id: 文章ID
  • 请求头
    • Content-Type: application/json
  • 响应
    1
    2
    3
    {
    "likes": 45
    }
  • 状态码
    • 200: 成功
    • 404: 文章不存在

DELETE /api/likes/{post_id}

功能:取消文章点赞

  • 方法:DELETE
  • 路径参数
    • post_id: 文章ID
  • 响应
    1
    2
    3
    {
    "likes": 44
    }
  • 状态码
    • 200: 成功
    • 404: 文章不存在

GET /api/likes/{post_id}

功能:获取文章点赞数

  • 方法:GET
  • 路径参数
    • post_id: 文章ID
  • 响应
    1
    2
    3
    {
    "likes": 45
    }
  • 状态码
    • 200: 成功
    • 404: 文章不存在

🏗️ FastAPI 实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Dict

app = FastAPI(title="Hexo Engagement API")

# CORS 中间件 (允许前端跨域请求)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 生产环境请指定具体域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

# 数据模型
class EngagementResponse(BaseModel):
views: int = 0
likes: int = 0

# 内存存储 (生产环境使用数据库)
views_db: Dict[str, int] = {}
likes_db: Dict[str, int] = {}

@app.post("/api/views/{post_id}")
async def record_view(post_id: str) -> EngagementResponse:
"""记录文章访问"""
views_db[post_id] = views_db.get(post_id, 0) + 1
return EngagementResponse(views=views_db[post_id])

@app.get("/api/views/{post_id}")
async def get_views(post_id: str) -> EngagementResponse:
"""获取文章访问计数"""
return EngagementResponse(views=views_db.get(post_id, 0))

@app.post("/api/likes/{post_id}")
async def like_post(post_id: str) -> EngagementResponse:
"""给文章点赞"""
likes_db[post_id] = likes_db.get(post_id, 0) + 1
return EngagementResponse(likes=likes_db[post_id])

@app.delete("/api/likes/{post_id}")
async def unlike_post(post_id: str) -> EngagementResponse:
"""取消文章点赞"""
current_likes = likes_db.get(post_id, 0)
if current_likes > 0:
likes_db[post_id] = current_likes - 1
return EngagementResponse(likes=likes_db[post_id])

@app.get("/api/likes/{post_id}")
async def get_likes(post_id: str) -> EngagementResponse:
"""获取文章点赞数"""
return EngagementResponse(likes=likes_db.get(post_id, 0))

# 健康检查端点
@app.get("/health")
async def health_check():
return {"status": "healthy"}

🗄️ 数据库建议

生产环境数据存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- 文章表
CREATE TABLE posts (
id VARCHAR(255) PRIMARY KEY,
title VARCHAR(500),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 访问计数表
CREATE TABLE views (
post_id VARCHAR(255) REFERENCES posts(id),
count INTEGER DEFAULT 0,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (post_id)
);

-- 点赞表
CREATE TABLE likes (
post_id VARCHAR(255) REFERENCES posts(id),
count INTEGER DEFAULT 0,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (post_id)
);

-- 用户点赞记录 (防止重复点赞)
CREATE TABLE user_likes (
id SERIAL PRIMARY KEY,
post_id VARCHAR(255) REFERENCES posts(id),
user_ip VARCHAR(45),
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(post_id, user_ip)
);

🔧 部署配置

环境变量

1
2
3
4
5
6
# FastAPI 配置
APP_ENV=production
DATABASE_URL=postgresql://user:password@localhost/hexo_engagement

# CORS 配置
ALLOWED_ORIGINS=http://localhost:4000,https://yourdomain.com

Docker 部署

1
2
3
4
5
6
7
8
9
10
FROM python:3.9-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .
EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

📊 监控和日志

建议监控指标

  • API响应时间
  • 错误率
  • 每日访问/点赞统计
  • 数据库连接状态

日志记录

1
2
3
4
5
6
import logging

logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

🔒 安全考虑

  1. 速率限制:防止API滥用
  2. 输入验证:验证post_id格式
  3. CORS配置:限制允许的域名
  4. HTTPS:生产环境必须使用HTTPS
  5. API密钥:可选的身份验证

🚀 启动命令

1
2
3
4
5
# 开发环境
uvicorn main:app --reload --host 0.0.0.0 --port 8000

# 生产环境
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4

📝 注意事项

  • 前端JavaScript会自动处理API失败的情况,使用front matter中的数据作为fallback
  • 确保API服务器与Hexo服务器在同一域名或正确配置CORS
  • 生产环境建议使用Redis或数据库进行数据持久化
  • 考虑实现用户会话管理以更好地跟踪用户行为