如何在 apollo graphql 服务器中编写解析 graphql 过滤器

Posted

技术标签:

【中文标题】如何在 apollo graphql 服务器中编写解析 graphql 过滤器【英文标题】:How to write resolve graphql filters in apollo graphql server 【发布时间】:2019-07-15 08:00:34 【问题描述】:

要求:

我需要建议编写解析器函数来处理 graphql 过滤器。该过滤器支持 eq、ne、like、contains 和 not like 运算符。

架构:

import  gql  from 'apollo-server-express';

export default gql`
   extend type Query 
       authGroups(filter: AuthGroupFilterInput): AuthGroupConnection!
    

    type AuthGroup implements Node 
       id: ID!
       name: String
    

    input AuthGroupFilterInput 
       name: StringFilterInput
    

    type AuthGroupConnection 
       edges: [AuthGroup!]!
       pageInfo: PageInfo
    

    input StringFilterInput 
      lt: String,
      gt: String,
      eq: String,
      ne: String,
      contains: String,
      like: String,
      notLike: String,
      

`;

GraphQL 查询:

 Query 
    authGroups(filter:   
          name: 
             like: '%AD'
          
       
      )
    
       edges 
         id
         name
       
    
 

解析器:

authGroups: async (parent, args,  models ) => 
        const filter = args.filter;
        const filters = filter 
                        ? 
                            where: filter,
                         
                        : ;

        const authGroups = await models.authGroup.findAll(
           ...filters
        //    where : 
        //        name: 
        //            [Sequelize.Op.like] : 'AD%'
        //        
        //    
        );  

使用的技术:

阿波罗服务器 快递 续集 PostgreSQL

如何将filter中的操作符替换为[Sequelize.Op.operator]?我尝试在 config.json 中使用operatorsAliases,但没有任何效果。非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

您可以只使用括号符号来访问Op 上的正确属性。像这样的:

function transformFilter (filter) 
  for (const fieldName in filter) 
    const condition = filter[fieldName]
    filter[fieldName] = 
    for (const operatorName in condition) 
      filter[fieldName][Op[operatorName]] = condition[operatorName]
    
  

括号表示法即使像这样“嵌套”也有效。

【讨论】:

我的笔记本电脑崩溃了,我正在恢复数据。尝试此解决方案后,我会回复您。 这个功能对我有用,我更喜欢这种方法,因为不强烈推荐 operatoraliases。我们如何扩展这个函数来支持 OR 运算符? 添加像andor 这样的运算符需要更复杂的逻辑。事实上,它可能需要您修改您设置模式的方式。这确实超出了这个问题的范围。看看how Graphcool does it 了解一些想法。【参考方案2】:

我通过在 Sequelize 构造函数中传递 OperatorAliases 解决了这个问题。

import Sequelize from 'sequelize';
const operatorsAliases = 
    eq: Op.eq,
    ne: Op.ne,
    gte: Op.gte,
    gt: Op.gt,
    lte: Op.lte,
    lt: Op.lt,
    ......

连接时在sequelize中使用这个别名..

const dbService = 
    connect: (host, database) => 
        const sequelize = new Sequelize(
            database,
            user,
            pwd, 
                host: host,
                dialect: 'yourDialect',
                dialectOptions: 
                    domain: domain,
                    encrypt: true
                ,
                operatorsAliases: operatorsAliases,
                pool: 
                    max: 100,
                    min: 10,
                    idle: 200
                
            
        );

        sequelize
            .authenticate()
            .then(() => 
                console.log(database, 'Connection has been established successfully.');
            )
            .catch((err) => 
                console.error(err, `Unable to connect to the database.`);
            );

        return sequelize;
    
;
const yourDBRef = dbService.connect(hostName, dbName);

它应该可以直接在您的解析器中运行,无需任何额外的努力。

  const authGroups = await models.authGroup.findAll(
        where :filters
    ); 

【讨论】:

我的笔记本电脑崩溃了,我正在恢复数据。尝试此解决方案后,我会回复您。 谢谢阿米特这个解决方案也对我有用。我在配置文件中定义操作符别名时犯了一个错误。我将操作符别名移到了创建 sequelize 实例的地方并且它工作了。

以上是关于如何在 apollo graphql 服务器中编写解析 graphql 过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jest / apollo 客户端中捕获被拒绝的 graphql 订阅?

使用 Apollo Server 时如何生成 schema.graphql 文件?

如何从 Apollo Server 端点获得完整的 GraphQL 架构?

如何使用特定上下文查询 Apollo GraphQL 服务器?

如何将图片从 TinyMCE 上传到 Apollo GraphQL 服务器?

如何将 redux 与 graphql 一起使用