Saphire
Saphire

Reputation: 1930

How to adapt query to API?

I'm trying to wrap my head around GraphQL.

Right now I'm just playing with the public API of Artsy (an art website, playground at https://metaphysics-production.artsy.net). What I want to achieve is following:

  1. I want to get all node types entities without declaring them by hand (is there a shortcut for this)?
  2. I want every node with a field type from which I can read the type, without parsing through imageUrl etc. to fint that out.

What I constructed as of right now is this:

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

Very primitive I guess. Can you guys help me?

Upvotes: 0

Views: 101

Answers (1)

nopassport1
nopassport1

Reputation: 1944

TL;DR:

1) There is no shortcut, it's not something GraphQL offers out of the box. Nor is it something I was able to find via their Schema.

2) Their returned node of type Searchable does not contain a property for type that you're looking for. But you can access it via the ... on SearchableItem (union) syntax.


Explanation:

For question 1):

Looking at their schema, you can see that their search query has the following type details:

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

The query accepts an entities property of type SearchEntity which looks like this:

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

Depending on what your usecase is, if you're constructing this query via some code, then you can find out which SearchEntity values they have:

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

Which returns:

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

      ...

    }
  }
}

then store them in an array, omit the quotation marks from the enum and pass the array back to the original query directly as an argument.

Something along the lines of this:

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

and in your query variables section, you just need to add:

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







As for question 2)

The query itself returns a SearchableConnection object.

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

Digging deeper, we can see that they have edges, of type SearchableEdge - which is what you're querying.

type SearchableEdge {
  node: Searchable
  cursor: String!
}

and finally, node of type Searchable which contains the data you're trying to access.

Now, the type Searchable doesn't contain type:

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

But, if you look at where that Searchable type is implemented, you can see SearchableItem - which contains the property of displayType - which doesn't actually exist in Searchable.

You can access the property of SearchableItem and get the displayType, like so:

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

and your result will look like this:

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

...

Upvotes: 2

Related Questions