Nestjs中如何遵循jsonapi规范实现接口标准化响应返回格式
符合JSON:API规范的实现优化方案
原有实现的问题
- 混合使用
await和.then()异步写法,逻辑冗余 - 响应结构不符合JSON:API的资源定义规则,自定义的
isError、message等字段属于冗余字段,不符合规范要求 - 资源对象没有按照要求拆分
id、type、attributes层级
核心调整规则
- 成功响应的顶级
data字段下,每个资源必须包含id(资源唯一标识)、type(资源类型,这里固定为products)、attributes(业务属性字段)三个部分 - 错误场景下返回顶级
errors字段替代data字段,错误状态直接使用标准HTTP状态码,不需要单独定义statusCode字段 - 统一使用
async/await写法优化异步逻辑,去掉冗余的中间变量
优化后代码实现
首先定义通用的JSON:API响应类型:
// 定义通用JSONAPI资源类型 type JsonApiResource<T> = { id: string | number; type: string; attributes: Omit<T, 'id'>; } // 成功响应结构 type JsonApiSuccessResponse<T> = { data: JsonApiResource<T> | JsonApiResource<T>[]; } // 错误对象结构 type JsonApiError = { status: string; detail: string; } // 错误响应结构 type JsonApiErrorResponse = { errors: JsonApiError[]; } type JsonApiResponse<T> = JsonApiSuccessResponse<T> | JsonApiErrorResponse;
修改接口逻辑:
async findAll(): Promise<JsonApiResponse<Product>> { try { const products = await this.repository.find(); // 转换为JSONAPI规范的资源格式 const resources: JsonApiResource<Product>[] = products.map(product => ({ id: product.id, type: 'products', attributes: { description: product.description, price: product.price, category: product.category, stock: product.stock, createDate: product.createDate, lastUpdateDate: product.lastUpdateDate } })); return { data: resources }; } catch (e) { const error = e as HttpException; return { errors: [ { status: error.getStatus().toString(), detail: error.message } ] }; } }
最终符合规范的响应示例
成功响应
{ "data": [ { "id": 1, "type": "products", "attributes": { "description": "Oreo", "price": "6.5", "category": "Oreo", "stock": 50, "createDate": "2021-10-28T14:11:47.454Z", "lastUpdateDate": "2021-10-28T14:11:47.454Z" } } ] }
错误响应
{ "errors": [ { "status": "500", "detail": "Internal server error" } ] }
内容的提问来源于stack exchange,提问作者Bruno Diaz
相关产品推荐
相关产品推荐

