首页 > 解决方案 > 如何使查询适应 API?

问题描述

我正试图围绕 GraphQL。

现在我只是在玩 Artsy 的公共 API(一个艺术网站,https ://metaphysics-production.artsy.net 的游乐场)。我想要达到的目标如下:

  1. 我想在entities不手动声明的情况下获取所有节点类型(是否有捷径)?
  2. 我希望每个节点都有一个字段type,我可以从中读取类型,而无需解析imageUrl等来找出它。

我现在构建的是这样的:

{
  search(query: "Berlin", first: 100, page: 1, entities: [ARTIST, ARTWORK, ARTICLE]) {
  edges {
    node {
      displayLabel
      imageUrl
      href
    }
  }
}}

我猜很原始。你们能帮帮我吗?

标签: graphql

解决方案


TL;博士

1) 没有捷径,这不是 GraphQL 开箱即用的东西。这也不是我能够通过他们的 Schema 找到的东西。

2) 他们返回node的类型Searchable不包含type您要查找的属性。但是您可以通过... on SearchableItem (union) 语法访问它。


说明

对于问题 1):

查看他们的架构,您可以看到他们的搜索查询具有以下类型详细信息:

search(
  query: String!
  entities: [SearchEntity]
  mode: SearchMode
  aggregations: [SearchAggregation]
  page: Int
  after: String
  first: Int
  before: String
  last: Int
): SearchableConnection

查询接受如下所示entities的类型属性SearchEntity

enum SearchEntity {
  ARTIST
  ARTWORK
  ARTICLE
  CITY
  COLLECTION
  FAIR
  FEATURE
  GALLERY
  GENE
  INSTITUTION
  PROFILE
  SALE
  SHOW
  TAG
}

根据您的用例,如果您通过一些代码构建此查询,那么您可以找出SearchEntity它们具有哪些值:

{
  __type(name: "SearchEntity") {
    name
    enumValues {
      name
    }
  }
} 

返回:

{
  "data": {
    "__type": {
      "name": "SearchEntity",
      "enumValues": [
        {
          "name": "ARTIST"
        },
        {
          "name": "ARTWORK"
        },

      ...

    }
  }
}

然后将它们存储在一个数组中,省略枚举中的引号并将数组作为参数直接传递回原始查询。

类似这样的东西:

query search($entities: [SearchEntity]) {
  search(query: "Berlin", first: 100, page: 1, entities: $entities) {
    edges {
    node {
      displayLabel
      imageUrl
      href
    }
  }
 }
}

在您的查询变量部分,您只需要添加:

{
  "entities": [ARTIST, ARTWORK, ...]
}







至于问题2)

查询本身返回一个SearchableConnection对象。

type SearchableConnection {
  pageInfo: PageInfo!
  edges: [SearchableEdge]
  pageCursors: PageCursors
  totalCount: Int
  aggregations: [SearchAggregationResults]
}

深入挖掘,我们可以看到它们具有edges, 类型SearchableEdge- 这就是您要查询的内容。

type SearchableEdge {
  node: Searchable
  cursor: String!
}

最后,包含您尝试访问的数据node的类型。Searchable

现在,该类型Searchable不包含type

type Searchable {
  displayLabel: String
  imageUrl: String
  href: String
}

但是,如果您查看该Searchable类型的实现位置,您会看到SearchableItem- 其中包含 - 的属性,displayTypeSearchable.

您可以访问 的属性SearchableItem并获取displayType,如下所示:

{
  search(query: "Berlin", first: 100, page: 1, entities: [ARTIST, ARTWORK, ARTICLE]) {
    edges {
      node {
        displayLabel
        imageUrl
        href
        ... on SearchableItem {
          displayType
        }
      }
    }
  }
}

您的结果将如下所示:

{
  "data": {
    "search": {
      "edges": [
        {
          "node": {
            "displayLabel": "Boris Berlin",
            "imageUrl": "https://d32dm0rphc51dk.cloudfront.net/CRxSPNyhHKDIonwLKIVmIA/square.jpg",
            "href": "/artist/boris-berlin",
            "displayType": "Artist"
          }
        },

...

推荐阅读