比方说,我在创建为Strapi内容类型的Author类型架构上具有' firstName '和' lastName '属性。
我可以使用graphql查询它们,但是如果我想查询' fullName '属性而不在我的内容类型上添加该字段怎么办?
由于该字段不存在,现在它说:无法查询类型为“ Author \”的字段“ fullName \”。
如何使用该附加的“虚拟”字段扩展现有的类型架构?
答案 0 :(得分:1)
我设法通过放置在 api / author / config 文件夹内的 schema.graphql 文件中的以下代码来做到这一点:
module.exports = {
definition: `type AuthorOverride {
firstName: String
lastName: String
fullName: String
}`,
query: `
authors: [AuthorOverride]
`,
type: {
Author: false
},
resolver: {
Query: {
authors: {
description: 'Return the authors',
resolver: 'Author.find'
}
}
}
};
关键是要在使用其他类型名称(AuthorOverride)的同时使用其他字段定义架构,以避免重复的类型错误。
还可以设置类型:{作者:false},以便原始类型不会被查询。
现在,在解析器函数“ Author.find”(位于Author.js控制器中)内,我可以映射fullName值。
如果有人对于在Strapi中扩展graphql模式有更合适的解决方案,请随时发布。
答案 1 :(得分:1)
刚刚找到这个帖子,也找到了合适的解决方案。此 example repo 演示了如何使用具有自定义控制器方法和自定义 GraphQL 架构的服务函数来获得您想要的。我刚刚在自己的项目中实现了相同的功能。
您的案例不需要服务功能。你只需要做两件事:
fullName
中定义 /api/authors/config/schema.graphql.js
属性,如下所示:module.exports = {
definition:
extend type Author {
fullName: AuthorFullName
}
type AuthorFullName {
firstName: String
lastName: String
}
`,
};
find
的 findOne
和 Author
控制器方法,如下所示:module.exports = {
async find( ctx ) {
let entities;
if ( ctx.query._q ) {
entities = await strapi.services.author.search( ctx.query );
} else {
entities = await strapi.services.author.find( ctx.query );
}
// Add computed field `fullName` to entities.
entities.map( entity => {
entity.fullName = `${entity.firstName} ${entity.lastName}`;
return entity;
} );
return entities.map( entity => sanitizeEntity( entity, { model: strapi.models.author } ) );
},
async findOne( ctx ) {
const { id } = ctx.params;
let entity = await strapi.services.author.findOne( { id } );
if ( ! entity ) {
return ctx.notFound();
}
// Add computed field `fullName` to entity.
entity.fullName = `${entity.firstName} ${entity.lastName}`;
return sanitizeEntity( entity, { model: strapi.models.author } );
},
};
这允许 REST API 调用获取返回的 fullName
并告诉 GraphQL 在其架构中也包含 fullName
,以便 find
和 findOne
可以将其传递给GraphQL 正确。
我希望这会有所帮助,因为我觉得我在学习了这个之后刚刚升级了很多时间!