Goal

At Digg, we had a simple service which would crawl a given URL and return
its title, a summary and any worthy images. Early Digg relied heavily on
unreliable scraping heuristics to extract these characteristics, but most
websites these days have enough social media metadata to greatly simplify
the process.

The project we're building is to recreate that crawling service, and we'll
build it using the extraction library
I wrote some years back (which was on my mind because I recently updated it
to be Python3 compatible).

In this case website is an object type that we support querying against,
url is a parameter that'll be passed along to the resolution function,
and then resolve_website is called by each request to a website object.

Note that there is a fair amount of magic happening here, with the names
having to match exactly for this to work. Most of my issues writing this
code were typos across fields, causing them not to match properly.
Also note that extract is the function we wrote in the previous section.

The final step is to create a graphene.Schema instance which you'll pass
to your server to describe the new API you've created:

Note that unless you've downloaded the example code, your schema will have a different import path.
It's also fine to put your schema and the server into a single file if you don't want to mess with
import paths.

Client

Although they exist, you don't need a special GraphQL client to
perform API requests against your new API, you can stick to the
http clients that you're used to, with us using requests
in this example.

Extending objects

Potentially the most interesting and exciting part of GraphQL is how
easy it is to extend your object without causing compatibility issues
in your client. For example, let's imagine we wanted to start returning
pages' RSS feed as well through a new feed field.

We can add it to Website and update our resolve_website method
to return the feed field as follows:

If you wanted to retrieve this new field, you'd just update
your query to also request it, in addition to the other
fields like title and image that you're already retrieving.

Introspection

One of the most powerful aspects of GraphQL is
that its servers support introspection,
which allow both humans and automated tools to understand
the available objects and operations.

The best example of this is that if you're running the example
we built, you can navigate to localhost:5000 and use
GraphiQL to directly test
your new API.

These capabilities aren't restricted to GraphiQL, you can also
integrate with them using the same query interface you'd use
to query your new API. A simple example would be we can ask about
the available queries exposed by our sample service:

There are a bunch of other introspection queries
available, which are a bit clumsy to write, but expose a tremendous amount of
power to tool builders. Definitely worth playing with!

Closing thoughts

Overall, I was quite impressed with how easy it was to work with GraphQL,
and even more impressed with how easy it was to integrate against.
This approach to describing objects was more intuitive to me than
gRPC's, with the later still being more akin to writing a protocol than
describing an object.

At this point, if I was writing a product API, GraphQL would be the
first tool I'd reach for, and if I was writing a piece of infrastructure,
I'd still prefer gRPC, especially for its authentication and tight HTTP/2
integration (for e.g. bi-direcitonal streaming).

Lots of additional questions to dig into here at some point:

How do they fair in terms of data compression?

Does compression even really matter if the servers are compressing the results?

Does GraphQL have worse protocol compression but
superior field compression since folks have to explicitly ask for what they
need?

How well do their field deprecation stories work in practicve? Both have some story around
deprecation, neither seeming ideal, with GraphQL's deprecation warnings seeming
a bit superior, since you could imagine writing your client libraries to surface
all deprecation warnings returned by the API with a log of some sort.

I'm sure there are a bunch more as well!

Hi folks. I'm Will, known as @lethain on Twitter.
I write about software and management topics,
and love email at lethain[at]gmail.
Get email from me by subscribing to
my weekly newsletter.