GraphQL, the New Contender to REST

Chariot Solutions
Jul 27, 2020 · 6 min read

The Representative State Transfer (REST) protocol has been the king of remote access protocols for web applications for well over a decade. The general pattern: expose “nouns” (Customers, Activities, Employees, Tasks, Sasquatches) as URLs (/api/sasquatch/32) and access them via HTTP “verbs” such as “GET”, “POST” (create), “PUT” (update), or “DELETE” (umm, well…). The content type is specified via HTTP headers such as Content-Type (for data being received by the client) and Accepts (for a data request).

The reason this works so well is that the HTTP protocol, devised by Roy Fielding in a Doctoral Thesis all those years ago, can describe just about anything. It usually devolves to exceptions to the rule (how do you handle commands? POST em?), but you can secure the traffic with SSL/TLS, you can represent the data in any format (XML, JSON, BSON, Protocol Buffers), and you can understand the type of request by reading it like a sentence:

GET /api/customersAccepts: application/json,text/plain

(I want to get all of my customers. When you send them to me, first try to retrieve them as JSON data, but if you can’t do that, I’ll take plain text. Just tell me with your response).

The Challenge: Death by a thousand endpoints…

As with all thrones, there are always contenders (and pretenders). The old SOAP protocol was ditched in favor of REST because of its simplicity and universality.

For a while in the late ’aughts, Flex (a Flash-based front-end that died because Steve Jobs decided Flash would never run on his phones) had an RPC-based remoting technology, BlazeDS, that was blisteringly fast. Spring Remoting has existed for a long time, but having a Java-based Applet or Java Web Start front-end is not what people want.

As long as we front our applications with web servers and HTTP, a challenger must live in that world.

Enter GraphQL. It exposes a single HTTP endpoint (/graphql for example) with a POST request, therefore living in the HTTP and SSL/TLS world, but sends queries to that endpoint using a query language. It provides (and exposes) a schema and metadata querying tools to define queries, modifications and data types. The data in the response is JSON-compatible, and the calls can be as coarse-grained or fine-grained as you need them to be.

REST -vs- RPC

So often, developers run into situations with REST where they have to learn within the noun-verb contraption, or just exit out with special POST APIs that don’t look super RESTful. For example:

POST /api/jobs/execute?job=tps-reports
POST /api/customers?nameLike=Fred&city=Catasaqua&numRows=300

It might be better to provide an endpoint that accepts RPC-style requests, like:

runTpsReports()
findCustomersByNameAndCity('Fred', 'Catasaqua', 300)

If the data returned is the acknowledgement of the job, it could either be a promise that resolves successfully with no payload, or possibly with a boolean or number. So you could run it via a promise:

try {
await runTpsReports();
} catch (e) {
console.log('it failed.', e);
// handle error
}
// it worked

Or even a simple finder function, like this.

let customers;
try {
customers = await findCustomersByNameAndCity(name, city, 300);
} catch (e) {
console.log('it failed', e);
// handle error
}

Before, you’d have to translate this into a particular REST call, and each resource would need its own REST endpoint. With GraphQL, you expose a schema, bound to resources on the backend, that you query.

Let’s look at a fictional GraphQL query for finding customers:

query findCustomers {
Customers {
id
name
city
}
}

No matter how big the “customers” type is, we can grab only the fields we want. If the “customers” type has an “orders” type embedded as a collection, we can just ask for those as well, even drilling down into the product attached to the order, if so defined:

query findCustomers {
Customers {
id
name
city
orderSummary {
orderId
orderDate
quantityOrdered
totalAmount
product {
name
}
}
}
}

Queries can be pre-defined, especially if they limit the number of rows or take parameters in code. For example, a query can be issued that is given a customer search pattern for name, a city, and the number of rows to return:

query findCustomersByNameAndCity($name, $city, $numRows) {
findCustomersByNameAndCity(
name: $name!, city: $city, numRows: $numRows) {
id
name
city
orderSummary {
orderId
orderDate
totalAmount
}
}
}

Right away we see that we have some degrees of freedom as a client. First, we can see that our parameters are naturally written via RPC-style calling semantics. The $name (required), $city (optional) and $numRows (optional, an int that is 300 if not passed) parameters come in via our call. The fields we want sent across the network are decided at the query, not by the server. And we can even ask for a graph of structures (if so provided by the API).

Here is a GraphQL Schema definition to handle the queries above:

type Customer {
id: ID!
name: String!
city: String!
orderSummary: [OrderSummary!]
}

type OrderSummary {
orderId: ID!
orderDate: String! (hold that thought)
totalAmount: Float
product: Product!
quantityOrdered: Float!
}

type Product {
productID: ID!
name: String!
description: String
quantityOnHand: Float!
}

query {
findCustomersByNameAndCity(
name: String!, city: String, numRows: Int = 300): [Customer!]!
}

Most of this schema can be easily read once we discuss some rules:

Major GraphQL Features

GraphQL isn’t just a query tool. It’s a fully-fledged remote application protocol that includes:

All of this and it’s JSON up and down, so you can even query GraphQL with the curl command line.

GraphQL Implementations

There are a number of GraphQL implementations (servers and clients) available for a wide variety of languages. Here is a small list:

Each GraphQL implementation implements the query language, type system, and protocol, but may vary in how API calls are wired, exposed, and managed.

Give it a try

GraphQL has a lot going for it over using plain-old REST. Since the type system and schemas are exposed on the endpoint, lots of third-party query tools exist (GraphQL even has its own GraphQL Playground) that can test queries, provide code completion, and allow passing of parameters. Check out Altair for an alternative desktop query tool.

Amazon AppSync

An exciting implementation of GraphSQL is Amazon’s AppSync, which serves database resources, Lambdas and other AWS infrastructure as GraphQL. It supports subscriptions, can be developed as the backend of an AWS Amplify application, which adds some code generation annotations for things like CRUD operations (the @model) annotation for access to DynamoDB tables, a @connection annotation for linking fields to relationships of other tables (think of it as a foreign key), and @auth for connecting to security in Amazon’s IAM authorization management system. See more about that in the Amplify SDK documentation.

You can see more details on the GraphQL query language in my Philly Emerging Tech talk PDF, Video, or just by following the tutorials on GraphQL.org. I’ll have more posts on GraphQL in the future that go into specifics of various implementations or techniques.

This post was originally written for the Chariot Solutions Blog by Ken Rimple, Chariot’s Director of Training & Mentoring. You can read the original post here.

Starting your next software project? Our software experts are here to help. Read more about our service offerings at Chariot Solutions, or contact us for a quote.

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Chariot Solutions

Written by

Chariot Solutions is a top IT consulting firm specializing in software and mobile development, and development in the cloud. Visit us at chariotsolutions.com.

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Chariot Solutions

Written by

Chariot Solutions is a top IT consulting firm specializing in software and mobile development, and development in the cloud. Visit us at chariotsolutions.com.

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store