Strapi中find和findOne方法的实现与使用

在 Strapi 中,find
和 findOne
是常见的查询方法。find
用于查询多条记录(通常支持分页、排序、过滤等),而 findOne
用于查询单条记录(通常通过 ID 或其他唯一条件查询)。以下是分别实现 find
和 findOne
的示例代码。
1. find
方法
find
方法用于查询多条记录,支持分页、排序、过滤和字段选择等功能。
示例代码
module.exports = {
async find(ctx) {
try {
// 从 ctx.query 中提取参数
const { query } = ctx;
// 分页参数
const page = parseInt(query.pagination?.page) || 1;
const pageSize = parseInt(query.pagination?.pageSize) || 10;
const offset = (page - 1) * pageSize;
// 排序参数
const sort = query.sort || { createdAt: 'desc' };
// 过滤参数
const filters = query.filters || {};
// 字段选择
const fields = query.fields || ['*'];
// 深度查询(populate)
const populate = query.populate || {};
// 构建 strapi.db.query 查询条件
const results = await strapi.db.query('api::article.article').findMany({
where: filters,
select: fields,
populate,
orderBy: sort,
limit: pageSize,
offset,
});
// 计算总数(用于分页元数据)
const total = await strapi.db.query('api::article.article').count({
where: filters,
});
// 构建响应
const response = {
data: results,
meta: {
pagination: {
page,
pageSize,
total,
pageCount: Math.ceil(total / pageSize),
},
},
};
return response;
} catch (error) {
console.error(error);
ctx.throw(500, 'Failed to fetch articles');
}
},
};
请求示例
GET /api/articles?pagination[page]=2&pagination[pageSize]=10&sort[createdAt]=desc&filters[title][$eq]=Hello World&fields[0]=title&fields[1]=content&populate[author]=true
2. findOne
方法
findOne
方法用于查询单条记录,通常通过 ID 或其他唯一条件查询。
示例代码
module.exports = {
async findOne(ctx) {
try {
// 从 ctx.params 中提取 ID
const { id } = ctx.params;
// 从 ctx.query 中提取参数
const { query } = ctx;
// 字段选择
const fields = query.fields || ['*'];
// 深度查询(populate)
const populate = query.populate || {};
// 构建 strapi.db.query 查询条件
const result = await strapi.db.query('api::article.article').findOne({
where: { id },
select: fields,
populate,
});
// 如果未找到记录,返回 404
if (!result) {
return ctx.notFound('Article not found');
}
// 返回结果
return {
data: result,
};
} catch (error) {
console.error(error);
ctx.throw(500, 'Failed to fetch article');
}
},
};
请求示例
GET /api/articles/1?fields[0]=title&fields[1]=content&populate[author]=true
3. 参数说明
find
方法参数
pagination[page]
:当前页码,默认为1
。pagination[pageSize]
:每页记录数,默认为10
。sort
:排序规则,例如sort[createdAt]=desc
。filters
:过滤条件,例如filters[title][$eq]=Hello World
。fields
:返回的字段列表,例如fields[0]=title&fields[1]=content
。populate
:深度查询,例如populate[author]=true
。
findOne
方法参数
id
:记录的唯一标识符,从 URL 路径中提取。fields
:返回的字段列表,例如fields[0]=title&fields[1]=content
。populate
:深度查询,例如populate[author]=true
。
4. 路由配置
确保在 config/routes.json
中配置了对应的路由:
{
"routes": [
{
"method": "GET",
"path": "/articles",
"handler": "article.find",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/articles/:id",
"handler": "article.findOne",
"config": {
"policies": []
}
}
]
}
5. 总结
find
:适用于查询多条记录,支持分页、排序、过滤和字段选择。findOne
:适用于查询单条记录,通常通过 ID 查询,支持字段选择和深度查询。- 参数提取:从
ctx.query
和ctx.params
中提取参数,动态构建查询条件。 - 错误处理:捕获并处理可能的错误,返回友好的错误信息。
通过以上实现,你可以创建与 Strapi v5 接口规范一致的 find
和 findOne
接口。