为分析平台设计GraphQL架构

时间:2017-11-21 21:15:46

标签: schema analytics graphql

我刚开始探索GraphQL作为我的分析平台API层的选项。

我的UI主要是从表格和图表构建的。大多数情况下,数据代表按维度分组的某些数据库列。

我从Microsoft找到了以下文章https://www.microsoft.com/developerblog/2017/09/28/data-independent-graphql-using-view-model-based-schemas/,描述了他们应该如何设计糟糕的GraphQL模式(见下文)。

type Query {
  channels(source: String!, query:String!, appId:String!, apiKey:String!): [Channel]
  lineCharts(source: String!, query:String!, appId:String!, apiKey:String!, filterKey:String, filterValues:[String]): [LineChart]
  pieCharts(source: String!, query:String!, appId:String!, apiKey:String!): [PieChart]
  barCharts(source: String!, query:String!, appId:String!, apiKey:String!, filterKey:String, filterValues:[String]): [BarChart]
}

type Channel {
  name: String
  id: Int
}

type LineChart {
  id: String
  seriesData : [Series]
}

type PieChart {
  id: String
  labels: [String]
  values: [Int]
}

type BarChart {
  id: String
  seriesData : [Series]
}

type Series {
  label: String
  x_values: [String]
  y_values: [Int]
}

在我看来,这种设计是严格的,强制将任何新图表添加到根查询中。如果不失去GraphQL的好处,架构如何更通用?

1 个答案:

答案 0 :(得分:3)

您可以使用union类型和inline/fragments

执行某些操作
union Chart = LineChart | PieChart | BarChart

type Query {
  charts(
    source: String!
    query: String!
    appId: String!
    apiKey: String!
    filterKey: String
    filterValues: [String]
  ): [Chart]
}

然后你可以让你的charts解析器带来所有图表并写下你的查询,如

fragment Identifiers on Chart {
  __typename
  id
}
query {
  charts(...) {
    ...on LineChart {
      ...Identifiers
      seriesData
    }
    ...on PieChart {
      ...Identifiers
      labels
      values
    }
    ...on BarChart {
      ...Identifiers
      seriesData
    }
  }
}

Identifiers会为您提供有关您正在处理的类型及其id的一些信息,但您可以将其扩展为您喜欢的任何类型,只要这些字段对于该联合上的所有类型都是通用的(或者您只能在某些类型上传播它)。

如果您不想引入所有图表,有两种方法可以解决:

  1. 仅为您想要的类型添加内联片段,但其余部分仍然在那里,以空对象的形式。
  2. 将另一个参数传递给代表您想要的类型的解析器
  3. P.S。您可以根据需要获得详细信息,还有interfacesinput types