跳到主要内容

插件类型详解

WaveYo-API 支持多种类型的插件,每种类型都有特定的用途和开发规范。

1. API端点插件

用途

提供RESTful API端点,处理HTTP请求和响应。

文件结构

plugins/
└── yoapi_plugin_demoapi/
├── __init__.py # 主文件,必须包含register函数
├── plugin.json # 插件元数据文件
├── requirements.txt # 插件依赖
├── .env # 插件环境变量(可选)
└── routers/ # 子路由(可选)
└── v1.py

代码示例

# plugins/yoapi_plugin_demoapi/__init__.py
from fastapi import APIRouter, Depends, HTTPException, status
from plugins.log import get_log_service

router = APIRouter(prefix="/api", tags=["demo-api"])

@router.get("/items")
async def get_items():
"""获取项目列表"""
return {"items": ["item1", "item2", "item3"]}

@router.get("/items/{item_id}")
async def get_item(item_id: int):
"""根据ID获取项目详情"""
if item_id > 100:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Item not found"
)
return {"item_id": item_id, "name": f"Item {item_id}"}

@router.post("/items")
async def create_item(name: str):
"""创建新项目"""
return {"message": f"Item '{name}' created", "id": 123}

def register(app, **dependencies):
# 获取日志服务
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)

app.include_router(router)
logger.info("API端点插件已注册")
logger.debug(f"注册的路由: {[route.path for route in router.routes]}")

2. 数据库服务插件

用途

提供数据库连接和CRUD操作服务。

文件结构

plugins/
└── yoapi_plugin_demodb/
├── __init__.py
├── plugin.json # 插件元数据文件
├── requirements.txt
├── .env
├── models.py # 数据模型
└── services.py # 服务类

代码示例

# plugins/yoapi_plugin_demodb/__init__.py
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from core.env_validator import get_env_validator, EnvVarType

class DatabaseService:
def __init__(self, db_url: str):
self.engine = create_async_engine(db_url, echo=True)
self.async_session = sessionmaker(
self.engine, class_=AsyncSession, expire_on_commit=False
)

async def get_session(self):
"""获取数据库会话"""
async with self.async_session() as session:
yield session

def register(app, **dependencies):
# 使用环境变量验证框架
validator = get_env_validator()
env_schema = {
"DB_URL": {
"type": EnvVarType.STRING,
"required": True,
"description": "数据库连接URL"
},
"MAX_CONNECTIONS": {
"type": EnvVarType.INTEGER,
"required": False,
"default": 10,
"min": 1,
"max": 100,
"description": "最大连接数"
}
}

try:
env_vars = validator.validate_env_vars("demodb", env_schema)
db_url = env_vars["DB_URL"]
max_connections = env_vars["MAX_CONNECTIONS"]
except ValueError as e:
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)
logger.error(f"环境变量验证失败: {e}")
raise

# 创建数据库服务
db_service = DatabaseService(db_url)
dependencies['db_service'] = db_service

logger = dependencies.get('log_service').get_logger(__name__)
logger.info(f"数据库服务插件已加载,最大连接数: {max_connections}")

3. 认证授权插件

用途

提供无侵入式的安全控制和权限管理。

文件结构

plugins/
└── yoapi_plugin_demoauth/
├── __init__.py
├── plugin.json # 插件元数据文件
├── requirements.txt
├── .env
├── middleware.py # 认证中间件
└── services.py # 认证服务

代码示例

# plugins/yoapi_plugin_demoauth/__init__.py
from fastapi import Depends, HTTPException, status
from fastapi.security import APIKeyHeader
from core.env_validator import get_env_validator, EnvVarType

api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)

async def api_key_auth(api_key: str = Depends(api_key_header)):
"""API密钥认证"""
if not api_key:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="API密钥缺失"
)

# 使用环境变量验证框架
validator = get_env_validator()
env_schema = {
"VALID_API_KEY": {
"type": EnvVarType.STRING,
"required": True,
"description": "有效的API密钥"
}
}

try:
env_vars = validator.validate_env_vars("demoauth", env_schema)
valid_api_key = env_vars["VALID_API_KEY"]
except ValueError as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="服务器配置错误"
)

if api_key != valid_api_key:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="无效的API密钥"
)

return api_key

def register(app, **dependencies):
log_service = dependencies.get('log_service')
logger = log_service.get_logger(__name__)

# 为需要认证的路由添加依赖
exempt_paths = ['/health', '/docs', '/openapi.json', '/']

for route in app.routes:
if (hasattr(route, 'path') and
hasattr(route, 'dependencies') and
not any(exempt_path in route.path for exempt_path in exempt_paths)):
route.dependencies.insert(0, Depends(api_key_auth))

logger.info("认证插件已加载,已为受保护路由添加认证")

4. 工具类插件

用途

提供通用工具功能和辅助服务。

文件结构

plugins/
└── yoapi_plugin_utils/
├── __init__.py
├── plugin.json # 插件元数据文件
├── requirements.txt
├── .env
└── tools.py # 工具函数

代码示例

# plugins/yoapi_plugin_utils/__init__.py
import hashlib
import json
from datetime import datetime, timedelta
from typing import Any, Dict

class UtilityService:
def __init__(self):
self.cache: Dict[str, Any] = {}

def generate_hash(self, data: str) -> str:
"""生成SHA256哈希"""
return hashlib.sha256(data.encode()).hexdigest()

def json_serializer(self, obj: Any) -> str:
"""JSON序列化工具"""
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")

def cache_get(self, key: str, default: Any = None) -> Any:
"""从缓存获取数据"""
return self.cache.get(key, default)

def cache_set(self, key: str, value: Any, ttl: int = 300) -> None:
"""设置缓存数据"""
self.cache[key] = {
'value': value,
'expires': datetime.now() + timedelta(seconds=ttl)
}

def register(app, **dependencies):
utility_service = UtilityService()
dependencies['utility_service'] = utility_service

logger = dependencies.get('log_service').get_logger(__name__)
logger.info("工具服务插件已加载")

选择适合的插件类型

插件类型适用场景复杂度依赖关系
API端点插件提供REST API低-中可能依赖数据库、认证服务
数据库服务插件数据持久化中-高数据库驱动、连接池
认证授权插件安全控制可能依赖用户服务、令牌服务
工具类插件通用功能通常无外部依赖

根据您的需求选择合适的插件类型,遵循相应的开发规范。