Strapi-如何使用自定义属性扩展graphql类型架构?

时间:2019-11-02 16:39:09

标签: graphql strapi

比方说,我在创建为Strapi内容类型的Author类型架构上具有' firstName '和' lastName '属性。

我可以使用graphql查询它们,但是如果我想查询' fullName '属性而不在我的内容类型上添加该字段怎么办?

由于该字段不存在,现在它说:无法查询类型为“ Author \”的字段“ fullName \”。

如何使用该附加的“虚拟”字段扩展现有的类型架构?

2 个答案:

答案 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 架构的服务函数来获得您想要的。我刚刚在自己的项目中实现了相同的功能。

您的案例不需要服务功能。你只需要做两件事:

  1. fullName 中定义 /api/authors/config/schema.graphql.js 属性,如下所示:
module.exports = {
  definition:
    extend type Author {
      fullName: AuthorFullName
    }

    type AuthorFullName {
      firstName: String
      lastName: String
    }
  `,
};
  1. 接下来,您需要覆盖 findfindOneAuthor 控制器方法,如下所示:
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,以便 findfindOne 可以将其传递给GraphQL 正确。

我希望这会有所帮助,因为我觉得我在学习了这个之后刚刚升级了很多时间!