简体   繁体   English

Apollo GraphQL 服务器中的别名字段

[英]Aliasing fields in Apollo GraphQL Server

Aliasing is very handy and works great when aliasing a specific resolver.别名非常方便,并且在为特定解析器别名时效果很好。 For instance:例如:

{
  admins: users(type:"admin"){
    username
  }
  moderators: users(type:"moderators"){
    moderators
  }
}

I'm not sure how to handle aliasing of the fields themselves though.我不确定如何处理字段本身的别名。 For example:例如:

{
  site_stats {
    hits: sum(field: "hits")
    bounces: sum(field: "bounces")
  }
}

If the resolver returns any sum value, the same value is aliased to both hits and bounces (which makes sense, since only a single sum value could even be returned).如果解析器返回任何sum值,则相同的值将被别名为hitsbounces (这是有道理的,因为甚至只能返回一个总和值)。 If I make the resolver use the alias names as the field names when returning the results, hits and bounces both become null .如果我让解析器在返回结果时使用别名作为字段名, hitsbounces都变成null

I could simply break those fields out into separate resolvers, but that complicates integration for the front end devs.我可以简单地将这些字段分解为单独的解析器,但这会使前端开发人员的集成变得复杂。 We would also lose a ton of efficiency benefits, since I can aggregate all the data needed in a single query to our data source (we're using ElasticSearch).我们还将失去大量的效率优势,因为我可以将单个查询中所需的所有数据汇总到我们的数据源(我们正在使用 ElasticSearch)。

Any help from you geniuses would be greatly appreciated!各位天才的任何帮助将不胜感激!

It sounds like you're putting all your logic inside the root-level resolver ( site_stats ) instead of providing a resolver for the sum field.听起来您将所有逻辑都放在根级解析器( site_stats )中,而不是为sum字段提供解析器。 In other words, if your resolvers look like this:换句话说,如果您的解析器如下所示:

const resolvers = {
  Query: {
    site_stats: () => {
      ...
      return { sum: someValue }
    },
  },
}

you should instead do something like:您应该改为执行以下操作:

const resolvers = {
  Query: {
    site_stats: () => {
      return {} // empty object
    },
  },
  SiteStats: {
    sum: () => {
      ...
      return someValue
    },
  },
}

This way you're not passing down the value for sum from the parent and relying on the default resolver -- you're explicitly providing the value for sum inside its resolver.这样,您就不会从父级传递 sum 的值并依赖于默认解析器 - 您在其解析器内显式地提供sum的值。 Since the sum resolver will be called separately for each alias with the arguments specific to that alias, each alias will resolve accordingly.由于将对每个别名分别调用sum解析器,并且 arguments 特定于该别名,因此每个别名将相应地解析。

Using aliases and single fields has very limited usability.使用别名和单个字段的可用性非常有限。

You can use complex filters (input params), fe list of keys to be returned and their associated params, fe您可以使用复杂的过滤器(输入参数),fe 要返回的键列表及其相关参数,fe

[{name:"hits", range:"month"}, 
{name:"bounces", range:"year"}]

With query - expected structure带查询 - 预期结构

{
  stats {
    name
    sum
    average
  }
}

Required fields may vary, fe only name and sum .必填字段可能会有所不同,只有namesum

You can return arrays of object fe您可以返回 object fe 的 arrays

{ stats: [
  { name:"hits", 
    sum:12345, 
    average: 456 }

Aliases can be usable here to choose different data sets fe name and sum for hits , bounces additionally with average .别名可以在这里用来选择不同的数据集 fe namesum for hits ,还加上average bounces

... more declarative? ...更具声明性?

PS. PS。 There is nothing that "complicates integration for the front end devs".没有什么“使前端开发人员的集成变得复杂”。 Result is json, can be converted/transformed/adapted after fetching (clinet side) when needed.结果是 json,可以在需要时在获取(clinet 端)后进行转换/转换/适配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM