GraphQL provides a query language to define the shape of data you’d like returned from an HTTP API on a server and a library to help make it happen. It’s easy to return a single item or multiple items.
Query Many Items
To query in graphql, you setup what looks like a json payload without the values. For example, to get the
title fields of all books in your API, you might write:
1 2 3 4 5 6
Query a Single Item
To query a single item, filtered by a unique id, you’d add a predicate to the books query:
1 2 3 4 5 6
Otherwise, everything remains the same.
The sameness or similarity with the single item query feels good from someone coming from a REST API, where resources similar to the above would be queried from URIs something like:
But keeping the same query field,
books, for both queries will provide a challenge because we will have to support both the single and multiple query from the same place.
Define a Schema
On the server, you need to define a schema for possible supported shapes of data you can query. We currently have one field that we can query –
books. In the case where we provide no filter (known as args in a schema), we want to return all books. If there is a filter, we want to use it, and return a single book. The schema might look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
The decision to return a single item or multiple items happens in the
resolve function for
books. And the
books field config shows that the return type will always be a
bookType. This means that whether a single item or multiple items, an array will always be returned. This doesn’t feel to terrible – even familiar when comparing to things like JSON-API. More importantly, it’s required for this return type to work.
At one point, I attempted to use
GraphQLUnionType to have two potential return types, but I got an error like:
…meaning that I couldn’t mix a single object type with an array type in the unioned return type.
So in our chosen, working solution above where we always return an array, any consuming client will query with the
books field. An array of one or many items will be returned. In the case of returning an array of a single item, the deserialization code will probably want to unwrap the item from the array and expose it as a single object, but obviously this is up to your preference.
There it is. Have you learned how to do this in a better or more elegant way?