GraphQL Query Crash Course

Crash course introduction to GraphQL

circle-info

The GraphQL API is an additional feature. If you would like to add the GraphQL Api to your Fast Weigh subscription, contact us at 865-219-2980 or [email protected]envelope.

If you are not familiar with GraphQL, no worries. It's easy to learn. If you have experience working with SQL you'll feel right at home. The syntax also looks similar to a JSON document if you are used to working with responses from REST endpoints. In fact, the structure of the query is simply the format of the JSON response you'd like to receive back.

Another nice feature of GraphQL is schema introspection. That's a fancy way of saying that the tables and fields are self-documenting. This allows us to build things like the Insomnia GraphQL Schema, which provides autocompletion and field documentation that is always up to date with the latest API changes. (🍻cheers to no documentation lag!)

GraphQL Query Basics

With GraphQL, you're still issuing a request to an HTTP endpoint just like you would for a REST API. The big difference is that there is a single endpoint that services all requests.

For Fast-Weigh, the endpoint looks like this:

https://graphql.fast-weigh.com/

Calling the endpoint directly

If you are calling the GraphQL endpoint directly, all requests must be POST requests with a JSON-encoded query as the body of the request (Content-Type: application/json)

Writing Your First Query

circle-info

Before you get started, make sure to read the previous articles covering the initial setup.

Authentication

Tooling

Here's a simple query that requests a few fields from the customers GraphQL type:

query Customers {
  customers {
    customerID
    customerName
    contactName
    contactPhone
  }
}

Let's break that syntax into its parts:

The Query Syntax

Operation Type

This is the specifier for what you want to do with the GraphQL API.

If you are familiar with REST APIs, you can think of this as the "HTTP Method" (PUT, POST, GET, etc). If you are familiar with SQL, you can think of this as the "SQL Command" (SELECT, INSERT, UPDATE, etc)

GraphQL endpoints support the following Operations:

  • query: ✅ Similar to a SQL SELECT statement (You are here!)

  • mutation: ✅ Similar to a SQL UPDATE or INSERT statement

  • subscription: ❌ A WebSocket-based live data stream

circle-info

Note that Fast-Weigh does not support the subscription type at this time.

Query Name

This is the identifier for the query. You can give it any name you'd like.

In the "Customers" example, the Query Name could have been "getAllCustomers", "get-customers-list", or anything else you could dream up. I went with "customers" for brevity.

Type

This can be an object or an array of many objects. Each Type contains one or more Fields of data. A Type can also contain other, related Types nested within it!

If you are familiar with REST APIs, you can think of this as similar to the specific endpoint you are calling. If you are familiar with SQL, you can think of this as the corresponding SQL table.

Field

A field is the actual piece of data that you want to return from the query.

If you are familiar with REST APIs, you can think of this as one of the values in the model for the endpoint. If you are familiar with SQL, you can think of this as the columns within the corresponding SQL table.

The Query Response

The response back from this query will be a JSON response matching the format of the query body.

Finding the Available Fields

GraphQL introspection powers autocomplete via the automatically generated Schema. If you navigate to the API endpoint directly, you can use our built-in tooling, but any API tooling should be able to fetch the schema!

Check out our GraphQL Schema article for more information about viewing the schema.

circle-info

Keep in mind that the GraphQL language is very case-sensitive! Check the schema or use auto-complete to make sure that you are entering the Type or Field with the correct spelling and case!

Joining via Relationships

GraphQL relationships work by "nesting" one or more additional types within a parent type. Since the data returned matches the query that you write, all relationship data will be self-contained within its parent type.

Relationships in GraphQL can be of 2 types:

  • Object: 1 to 1

  • Array: 1 to many

Object relationships

Object relationships will embed a single "sub-type" in the response.

For example, there can only be one Tax Code assigned to a Customer, so the customer type has an Object Relationship with a taxCode.

So a query like this:

Will result in a response that looks like this:

Array Relationships

Array relationships will nest a list of multiple objects in the response.

For example, a Customer can have many Orders created for the Customer, so the customer type has an Array Relationship with orders.

circle-info

Generally, it is best practice to try to avoid Array Relationships when you can. You should aim to write GraphQL queries from the "bottom up" with the most "detailed" object as your primary, parent type and multiple Object Relationship sub-types beneath it.

Querying for the Orders would look something like this:

And result in:

circle-info

Note the brackets [ ] containing multiple objects for the array data instead of a single set of curly brackets { }.

Filtering Data

Until now, the queries we've written would have returned all results from the Customer table. To filter the results, GraphQL supplies us with a few syntax options.

Where Clauses

Let's modify the query once again and supply a where argument.

The where argument can apply a number of different filters to a given field.

  • eq: equal to

  • neq: not equal to

  • gt: greater than

  • ngt: not greater than

  • gte: greater than or equal to

  • ngte: not greater than or equal to

  • lt: less than

  • nlt: not less than

  • lte: less than or equal to

  • nlte: not less than or equal to

  • in: exists in an array of values

  • nin: does not exist in an array of values

  • contains: matches some part of the given string

  • ncontains: does not match some part of the - given string

  • startsWith: matches the start of the given string

  • nStartsWith: does not match the start of the given string

  • endsWith: matches the end of the given string

  • nEndsWith: does not match the end of the given string

Here's an example of querying for just Customers in the State of Tennessee:

And here's an example of passing an array of States to the filter using the in clause:

Using multiple filters

You can use the and / or operators along with the other "where" filters to create more complex queries.

  • and: Data must satisfy all of the included filters

  • or: Data must satisfy at least one of the included filters

These operators open up an array using [ ] brackets that contain all the filters you wish to apply.

and:

This query will return Customers within Tennessee who are also marked as an "Open Account".

or:

This query will return Customers who are marked as "Open Accounts" or "Cash Only"

Filtering on Nested Types

Remember that filters can also be used on nested Types as well. But there is a difference for "where" filters in Object vs Array relations.

Object relationship "where" filter

For Object relationships, you'll apply the filter on the parent. For example, a Customer can only have a single TaxCode. So to filter the Customers TaxCode, you could write:

Array relationship "where" filter

For Array relationships, you'll still apply the where clause on the parent, but you will need to add a special "array" clause after the nested Type and before the Type Field filters.

  • any: Check if the nested type has any records

  • all: Every array type must match the filter

  • none: Every array type must NOT match the filter

  • some: One or more of the array type must match the filter

For example, a Customer can have many Orders. So to filter the Orders returned, you would write:

If you wanted to check if the Customer has any Orders, you could use the any clause:

Ordering Data

Building on the query above, you can order the results by adding an order field to your arguments.

circle-info

You must pass an object to the order argument with the field you'd like to order, as well as the sort direction.

The following sort directions are permitted:

  • ASC: ascending order

  • DESC: descending order

You can also sort on multiple fields by passing an array of objects to the order argument

Compound queries

Completely separate requests can also be merged within a single query. This is useful if you need to bring in data from multiple tables and only want to make a single HTTP call to do so.

circle-info

Typically, compound queries would only be used to stitch together the responses of smaller queries. You would not want to combine multiple large payload queries in the same request/response as this can be quite taxing to fetch and parse due to query complexity and payload size.

Here's an example request for some base resources within Fast-Weigh. These lists are generally quite short and are good candidates for compound queries if applicable to your use case.

Results in:

Using Parameters

Parameters allow you to pass data into your GraphQL statement from outside of the query body.

You can define one or more parameters by adding them to the very top of the query by the Query Name. Here is our original Query Syntax example, with a parameter added:

circle-info

Note the $ in front of the parameter name! This character is what tells GraphQL that something is a parameter, and it is required at the beginning of the parameter name.

Common parameter types

  • String: Represents textual data.

  • Int: Represents a number.

  • Boolean: Represents true or false values.

  • LocalDate: Represents an ISO formatted datearrow-up-right without time.

  • DateTime: Represents and ISO formatted datetimearrow-up-right.

  • Enums: These are special types that are pre-defined in the schema. For example, Order PayType is represented by an Enum called PayType.

    • You can view these in the schema and even query some of them just like you would any other Type.

It's important to note that dates must be formatted as YYYY-MM-DD when being passed as parameters.

circle-info

You might notice that some parameter types have an ! at the end. This means that the parameter is required if it is called, and it cannot be left blank.

Here is an example of our Customers by State query, but using a parameter to set the State, instead of hard-coding it in.

Query:

GraphQL Variables

Parameter arrays

Parameter arrays can be used for filters like in and are defined with [ ]'s.

  • [String]: An array of Strings

  • [Int]: An array of Ints

circle-info

These can also be required, but pay close attention to where the ! is located! If the ! is inside of the brackets, that means that the value in the array is required and cannot be blank. If the ! is outside of the brackets, that means the entire array is required!

Here is an example of our Customers by State query with multiple states passed in the parameter.

Query:

GraphQL Variables

Using Multiple Parameters

You can also pass multiple parameters within your query. Here is our CustomersByState query, with an added variable for the Customer's Credit Status Enum type:

Query:

GraphQL Variables

circle-info

Notice that since the CreditStatus Field is an "Enum Type"; we define the parameter as CustomerCreditStatus! instead of String!

Putting Queries Into Practice

Once you've got the query basics down, it's time to start experimenting and using them for your own use case or start quering via HTTP and code in your programming language of choice.

GraphQL for Developers

GraphQL Query Examples

Simple Trucks Query

Query Body

Query Variables

Simple Customers Query

Query Body

Query Variables

Simple Orders Query

Query Body

Last updated