Introduction to GraphQL

If you’ve never used GraphQL or want to know a bit more about the language and why companies like Yonomi have standardized on it, this is the place to start.

This guide will provide a high-level overview of the language along with some examples of how it’s used and links to resources where you can learn more. While this isn’t intended to be an exhaustive training on GraphQL, it’s a good place to start. We’ve also include links to additional training resources at the bottom of this guide.

What is GraphQL?

GraphQL - or Graph Query Language - is a query language for APIs. The language - along with the runtime engine used to process queries sent by a client - make up a GraphQL implementation. GraphQL sits in front of an aplication’s data, responding to client queries in a standard request-response paradigm to fulfill requests for data.

GraphQL is used in a similar to way to existing web-based APIs, with a client sending requests and a server responding to those requests.

Ok…but what is a Graph?

While the term, “query language” may be well understood by technical and non-technical folks alike, the other term - “graph” - may not be.

Graphs are used to solve real-world problems that involve representation of a problem space as a network. In the real world, a graph is well-understood as a pictoral or diagrammatic representation of values and how they relate. Graphs resemble the natural way we build mental models and relate concepts together, and help humans represent those real-world concepts in a graphical or digital domain.

Graphs are often represented by a set of nodes - or points - and the relationships between those nodes. As an example, in a graph representing a family tree, a person could be represented as a point/node and lines connecting to other points would represent the relationships between that person and other family members. Such a graph would readily represent the person’s relationships to their parents, grandparents, siblings and children.

In software engineering, graphs perform the same function.

The graph below pictorally represents different kinds of Yonomi Platform objects (users, devices, traits) and the lines represent the relationships between those objects.

Graph in the real world

In software engineering, graphs perform the same function, describing the problem domain in terms of objects and relationships between those objects.

Graph in the digital world

GraphQL represents the objects in a problem domain and the relationships between those objects through the GraphQL Schema. The GraphQL schema defines exactly what objects exist in the problem domain, how those objects relate to each other and can be done with or to those objects.

Using the concept of a digital problem domain coupled with a language for querying against that domain, GraphQL offers a flexible and dynamic way to interact with data over an API.

Why use GraphQL? Why not just use an established standard everyone already knows such as REST?

GraphQL was invented to improve the way web APIs - and in particular, REST-based web APIs - operate to accomplish the job of fetching data. While both REST and GraphQL work on the premise of sending an HTTP request and getting back a response, how clients send those requests and what responses they can get back are different. The difference in the request/response paradigm between REST and GrapnQL represents a significant change that makes GraphQL a more flexible and dynamic tool for API-based integration than its REST-based predecessor.

GraphQL vs. REST: Important Differences

Let’s dive into major differences between a REST-based API and a GraphQL-based API that make GraphQL a welcome addition to a web-based development toolset.

Coupled vs. Decoupled Resource Identity

In REST, resources are identified by the URL used to access them. Retrieving a device resource, for example, would typically be accessed by performing a GET call against the /device endpoint.

// GET on /devices returns the following:

{
  "id": "1ee54fa9003aeb452ca631ad3942a1",
  "name": "Front Door Lock", 
  "model": "Schlage Encode",
  // ... more fields here
}

The resource itself is bound to the mechanism by which the resource is retrieved. In addition, the type, or shape of the retrieved resource is defined by the endpoint itself. This approach is fine if you need the entire resource, but if you only want to retrieve a portion of the resource, you’ll need to serialize the returned JSON to get to the relevant information for your needs.

In GraphQL, resources are not bound to any specific endpoint. Instead, all resources are typically accessed from the same endpoint, and clients send a POST call with a request body to describe what resource or resources they are requesting to be retrieved.

me {
  devices {
    edges {
      node {
        id
        name
        model
      }
    }
  }
}

Client-defined Responses vs Server-defined Responses

While the two calls above retrieve similar results, note one important difference in the REST call:

// ... more fields here

The indication here is that the REST call will return back all of the contents of the resource available at the endpoint retrieved. With REST, the server defines the response.

With GraphQL, on the other hand, the client defines the response, and the server returns exactly and only what was requested by the client. GraphQL ensures that the developer and application only loads the relevant and absolute necessary data, even if it’s from multiple sources.

Since the GraphQL request body defines exactly what is to be returned, GraphQL is much more flexible in terms of its ability to allow the client to define specifically and only the data it needs to fulfill a request. There are a number of savings to be gained from this approach, but generally speaking, it’s a more flexible model for API interaction. This also means there’s a bit of a learning curve to GraphQL as the logic that defines each the request lives in the client itself.

CRUD Operations: REST GETs, PUTs, POSTs and DELETEs vs. GraphQL Queries & Mutations

In REST, you specify a write by changing the HTTP request method from GET to something else like POST, PUT or DELETE. This standard practice indicates to API users and the server that the intended purpose of the command being sent is differentiated between Read commands versus Create, Update or Delete commands.

GraphQL by and large rely on HTTP request methods in this way. GraphQL servers typically accept GET and POST methods, but the request payload itself defines the purpose of the request, not the request method. In other words, whether you’re performing a Create, Read, Update or Delete, the HTTP request method you’ll use will be either of GET or a POST. The only difference between using either of these methods is that when sending a GET, the payload is received as part of the HTTP query string, whereas when sending a POST the payload is sent in the HTTP body. The same command can be sent via GET or POST.

Strict/Strong vs. Relaxed/Loose Data Typing

Let’s start this topic by acknowledging that REST by no means precludes the use of strictly typed data payloads, and JSON is only one of several options for data formatting when using REST. Indeed, while JSON is a loosely typed format on its own, it can indeed by strictly typed, and has its own mechanism for schema definition to enfore strict typing. That said, GraphQL specifies strict typing as part of the language definition. REST does not require enforced typing (and many developers prefer it that way).

Strong typing allows client tools to validate code written is both syntatically correct and valid before the calls is executed. This approach can help speed up development and debugging over loosely typed formats by empowering clients to work against the schema as a contract for valid code. Strong typing also means GraphQL supports introspection, ensuring that any inbound code can be validated before it’s processed for a more efficient development process.

GraphQL is a language, REST is an architecture pattern

REST is an architectural concept and pattern for web-based data transmission between a client and a service. REST is not a language by itself, and the developer of a REST-based service has choice in defining many aspects of how their service leverages this pattern to support data transmission.

GraphQL is a query language, specification and set of tools explicitly defined for a specific model of client-server interaction. Implementing the specification means following the rules outlined in the specification to create a standard GraphQL service that anyone can use.

GraphQL combined with Yonomi Traits: A powerful couple

Yonomi’s use of GraphQL compliments another design decision: Traits. Traits are data models for defining device behaviors and attributes in a standard way across device types and brands. As an example, all light makers define a behavior for power on and power off actions against their light, but they are all defined and exposed differently by each brand’s vendor-specific API. Yonomi Traits normalize the interaction with all lights - regardless of type - by defining a Power trait, used to control any light without having to worry about the vendor-specific details of the action request.

Layering on Graphql, a single query can use the Power trait to power off all lights in a home - regardless of brand - and even power off any other devices that implement the Power trait such as fans, ACs and coffee pots.

Traits standardize the model for representing devices while GraphQL simplifies the model for interacting with devices. Together, they make for a faster, more flexible IoT solution development experience.

Additional GraphQL Resources

Now that we’ve provided an overview of GraphQL from our perspective, below are some useful resources for learning more about the language itself. Note that Yonomi does not promote or have a relationship with any of the providers or links below.

  1. GraphQL.org - This is the first and best place to start learning the GraphQL Language. It is a guided walkthrough with has extensive coverage of the language and code examples that you can run right from within your browser. There’s nothing to install, set up or configure to get started learning GraphQL. Completing this series of guides should put you in a great place to start working with Yonomi Platform.

  2. The FullStack GraphQL Tutorial at How To GraphQL - Once you’ve browsed the site above, you can dig in more thoroughly with setting up your own environment and building GraphQL examples from scratch. You may not need to go all the way through this tutorial before coming back to dive into the Yonomi Platform.

  3. Free Code Camp’s Novice to Expert GraphQL Video Tutorial - If you prefer a video-based training, this free guide is a good place to start. The channel may have released more up-to-date training videos by the time you read this.

  4. Yonomi GraphQL Schema - Working with GraphQL requires being familiar with the GraphQL implementation with which you are working. Browse here to review and understand what objects exist in the Yonomi GraphQL implemenation.

  5. Yonomi Traits Overview and Traits Reference - The Yonomi Traits overview and Traits referencw will help you get an understanding of how device traits work and what traits exist.

You’re ready to GraphQL with Yonomi

While GraphQL may not be familiar to your team, we think that once they’ve mastered this skill, you’ll find this approach results in faster development, more flexible solutions and a more intuitive user experiences for your developers and your users.

[Traits Reference] doc:util-traits-guides-generated-traits-reference [Yonomi Traits Overview] doc:util-traits-guides-traits-overview [Traits]