fix: example改为字段描述和example
This commit is contained in:
15
AGENTS.md
15
AGENTS.md
@@ -25,8 +25,19 @@
|
||||
- 所有接口以 `/api` 为前缀
|
||||
- 所有接口按照 `tsoa` 规范来编写,参考 `src/controllers` 目录下的 `UserController`、`GroupController` 示例
|
||||
- 如果接口需要登录,请使用 `@Security('jwt')` 装饰器,tsoa 会自动调用登录校验,并把 user 信息写到req上,参考 `UserController` 示例
|
||||
- **每个接口都需要通过 `@Example` 装饰器,写接口返回数据的示例,至少写一个例子**
|
||||
- **如果有入参,每个接口还需要通过 `@Example` 装饰器,再写一个接口入参数据的示例,至少写一个例子。没有入参则不用写例子**
|
||||
- **每个接口相关的类型定义(如interface、type)等,都需要按照标准注释进行类型及字段的描述注释。不明确的字段,如string类型的日期等,还需要加上 @example 表明字段具体的格式示例**,例如:
|
||||
```ts
|
||||
/**
|
||||
* 用户ID
|
||||
* @example "123456"
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* 注册日期,格式为yyyy-MM-dd
|
||||
* @example "2025-01-01"
|
||||
*/
|
||||
registryDate: string;
|
||||
```
|
||||
|
||||
### 3. 开发规范
|
||||
- **文件命名**: 使用kebab-case命名文件和文件夹
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Controller, Get, Route, Response, Tags, Request, Security, OperationId, Example} from 'tsoa';
|
||||
import {Controller, Get, Route, Response, Tags, Request, Security, OperationId} from 'tsoa';
|
||||
import {ApiError, ApiResponse} from '../types/api';
|
||||
import type {Request as ExpressRequest} from 'express';
|
||||
import axios from "axios";
|
||||
@@ -50,23 +50,6 @@ export class GroupController extends Controller {
|
||||
@Response<ApiResponse<UserInfo[]>>(200, 'Success')
|
||||
@Response<ApiResponse<null>>(400, 'Bad Request')
|
||||
@Response<ApiResponse<null>>(401, 'Unauthorized')
|
||||
@Example<ApiResponse<UserInfo[]>>({
|
||||
code: 200,
|
||||
message: 'success',
|
||||
data: [
|
||||
{
|
||||
userId: 123,
|
||||
nickname: 'John Doe',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
gender: 'MALE',
|
||||
nimToken: 'nim_token_123',
|
||||
nimAccountId: 'nim_account_123',
|
||||
token: 'user_token_123',
|
||||
updatedAt: '2024-01-01 00:00:00',
|
||||
createdAt: '2024-01-01 00:00:00',
|
||||
},
|
||||
],
|
||||
})
|
||||
public async getGroupMembers(@Request() req: ExpressRequest): Promise<ApiResponse<UserInfo[]>> {
|
||||
const user = req.user;
|
||||
const groupId = req.headers.groupid;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Controller, Get, Route, Response, Tags, OperationId, Example} from 'tsoa';
|
||||
import {Controller, Get, Route, Response, Tags, OperationId} from 'tsoa';
|
||||
import type { ApiResponse } from '../types/api';
|
||||
|
||||
@Route('api')
|
||||
@@ -12,11 +12,6 @@ export class TestController extends Controller {
|
||||
@Get('/test')
|
||||
@OperationId('Test_GetTest') // MUST: Specify operationId for better API documentation
|
||||
@Response<ApiResponse>(200, 'Success')
|
||||
@Example<ApiResponse>({
|
||||
code: 200,
|
||||
message: 'success',
|
||||
data: null,
|
||||
})
|
||||
public async getTest(): Promise<ApiResponse> {
|
||||
return {
|
||||
code: 200,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {Controller, Get, Route, Response, Tags, Example, Request, Security, OperationId} from 'tsoa';
|
||||
import {Controller, Get, Route, Response, Tags, Request, Security, OperationId} from 'tsoa';
|
||||
import type { ApiResponse } from '../types/api';
|
||||
import type { Request as ExpressRequest } from 'express';
|
||||
import type {UserInfo} from "../types/user";
|
||||
@@ -17,21 +17,6 @@ export class UserController extends Controller {
|
||||
@Security('jwt')
|
||||
@Response<ApiResponse<UserInfo>>(200, 'Success')
|
||||
@Response(401, 'Unauthorized')
|
||||
@Example<ApiResponse<UserInfo>>({
|
||||
code: 200,
|
||||
message: 'success',
|
||||
data: {
|
||||
userId: 123,
|
||||
nickname: 'John Doe',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
gender: 'MALE',
|
||||
nimToken: 'nim_token_123',
|
||||
nimAccountId: 'nim_account_123',
|
||||
token: 'user_token_123',
|
||||
updatedAt: '2024-01-01 00:00:00',
|
||||
createdAt: '2024-01-01 00:00:00',
|
||||
}
|
||||
})
|
||||
public async getUserGroupInfo(@Request() req: ExpressRequest): Promise<ApiResponse<Omit<UserInfo, 'token'>>> {
|
||||
const { token, ...rest } = req.user;
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
/**
|
||||
* Standard API response structure
|
||||
*/
|
||||
export interface ApiResponse<T = any> {
|
||||
/**
|
||||
* HTTP status code, e.g., 200 for success, 400 for client error, 500 for server error
|
||||
*/
|
||||
code: number;
|
||||
/**
|
||||
* Response message, e.g., "success" or error description
|
||||
*/
|
||||
message: string;
|
||||
/**
|
||||
* Response data; can be null if no data is returned
|
||||
*/
|
||||
data: T | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
/**
|
||||
* User information interface
|
||||
*/
|
||||
export interface UserInfo {
|
||||
/**
|
||||
* User ID
|
||||
*/
|
||||
userId: number;
|
||||
/**
|
||||
* User nickname
|
||||
*/
|
||||
nickname: string;
|
||||
/**
|
||||
* Avatar URL
|
||||
* @example "https://example.com/avatar.jpg"
|
||||
*/
|
||||
avatarUrl: string;
|
||||
gender: 'MALE' | 'FEMALE' | 'UNKNOWN';
|
||||
nimToken: string; // NetEase Cloud Communication token
|
||||
nimAccountId: string; // NetEase Cloud Communication account ID
|
||||
token: string; // Authentication token
|
||||
updatedAt: string; // yyyy-MM-dd HH:mm:ss
|
||||
createdAt: string; // yyyy-MM-dd HH:mm:ss
|
||||
/**
|
||||
* NetEase Cloud Communication token
|
||||
*/
|
||||
nimToken: string;
|
||||
/**
|
||||
* NetEase Cloud Communication account ID
|
||||
*/
|
||||
nimAccountId: string;
|
||||
/**
|
||||
* Authentication token
|
||||
*/
|
||||
token: string;
|
||||
/**
|
||||
* Last update time yyyy-MM-dd HH:mm:ss
|
||||
* @example "2023-10-05 14:48:00"
|
||||
*/
|
||||
updatedAt: string;
|
||||
/**
|
||||
* Account creation time yyyy-MM-dd HH:mm:ss
|
||||
* @example "2023-10-05 14:48:00"
|
||||
*/
|
||||
createdAt: string;
|
||||
}
|
||||
Reference in New Issue
Block a user