【问题标题】:Apollo GraphQL Custom Datasource Set Default FilterApollo GraphQL 自定义数据源设置默认过滤器
【发布时间】:2021-01-27 22:00:01
【问题描述】:

对于 Apollo GraphQL Server 自定义数据源,将默认 where 子句添加到每个数据库查询的最佳方法是什么,例如

where isDeleted = false

使用 Apollo GraphQL Server,我创建了一个自定义数据源。数据源只是从数据库中获取数据。

class CustomDataSource extends DataSource {

我已经扩展了 CustomDataSource,以便可以向其中添加项目特定的详细信息。即 CustomDataSource 应该是 vanilla 并且可以跨项目重用,而 MyProjectDataSource 可以包含项目特定的业务规则。

class MyProjectDataSource extends CustomDataSource {

我的 GraphQL 查询接受过滤器参数,并且 CustomDataSource 将过滤器应用于数据库查询。

type Query {
  users(filter: JSON): [User]
}

我的 customDataSource 是头重脚轻的,所以确实包含返回所有查询数据的连接。

实施思路

  1. MyProjectDataSource 更改/覆盖过滤器参数,然后调用 CustomDataSource。更改查询参数很简单,但不清楚是否可以(或建议)更改子字段参数。我正在使用 npm 模块 graphql-parse-resolve-info 进行字段前瞻。
async get(args, info) {
  args.filter = 'where isDeleted = false'
  return super.get(args, info);
}
  1. MyProjectDataSource 覆盖 CustomDataSource 函数。缺点:似乎过于复杂。也许公开一个可以被覆盖的“getFilter”函数可能会起作用,但覆盖函数感觉就像是一种大锤方法。

  2. 添加一个新的 defaultFilter 参数。缺点:我们不想将此参数暴露给应用程序。

  3. 创建一个 defaultFilter 指令。缺点:使架构复杂化。需要在整个架构中手动添加。不清楚如何在 MyProjectDataSource 中实现,和上面的 2 有相同的实现缺点。

  4. 使用 NodeJS eventEmitter 允许 CustomDataSource 覆盖过滤器参数。缺点:必须为所有项目特定规则添加到 CustomDataSource 的挂钩。

// CustomDataSource to emit event (and pass filter argument).
eventEmitter.emit('filter', ...

// MyDataSource to listen for event (and override filter argument).
eventEmitter.on('filter', ...
  1. 创建自定义过滤器数据类型(而不是 JSON 类型)。也许这个过滤器类可以公开一个 defaultFilter 属性。缺点:感觉就像添加一个简单的需求是一条复杂的道路。

【问题讨论】:

    标签: graphql apollo


    【解决方案1】:

    我找不到任何 Apollo Server 架构来帮助实现此功能。所以我决定使用这种简化的方法:

    class CustomDataSource extends DataSource {
      // Override this method in MyProjectDataSource (optional).
      static onFilterEvent(args, info, eargs) {
        return eargs;
      }
    
      // Add filter.
      eargs = { filter: get(args, 'filter') };
      eargs = this.constructor.onFilterEvent(this.args, this.info, eargs);
      if (eargs.filter) {
        // Run database query with modified filter in eargs.filter.
      }
    }
    
    class MyProjectDataSource extends CustomDataSource {
      static onFilterEvent(args, info, eargs) {
        eargs.filter = { isDeleted: false }; // TODO: If existing filter then use and clause.
        return eargs;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2013-03-05
      • 2019-04-10
      • 1970-01-01
      • 2014-11-16
      • 2012-12-28
      相关资源
      最近更新 更多