The Best Collected Details on the GraphQL Specification — Overview & Language
Original Post: https://compositecode.blog/2021/12/29/the-best-collected-details-on-the-graphql-specification-overview-language/
Reference https://spec.graphql.org
GraphQL, a query language and execution engine is described in this specification based on capabilities and requirements of data models for client-server applications. This article details and elaborates on the specification, the features and capabilities of GraphQL and implementations. I hope this collection of details around the GraphQL Specification can be used as a reference and launch point into learning about GraphQL use, implementation — server and client side — and ongoing references during future specification additions or changes!
The Humans
Every aspect of languages and specifications are created with context of an end user human. The specification is a project by the Joint Development Foundation, with a current Working Group charter that includes the IP policy governing all working group deliverables (i.e. new features, changes of spec, source code, and datasets, etc). To join the Working Group there are details for membership and details in the agreement for joining the efforts of the group.
Licensing, Notation, Grammar, & Syntax
Current licensing for the GraphQL Specification and related Working Group deliverables fall under the Open Web Foundation Agreement 1.0 Mode (Patent and Copyright).
The syntax grammar and related specifics are laid out in the document, which for this article it isn’t necessary to dig through the specifics of this. The research done and collected for this article has that covered for you dear reader, however if you do dig into the specification itself I strongly suggest reading these to insure you specifically know what is represented by what.
Description of GraphQL
The specification starts off with a detailed description of GraphQL. More detailed than a lot of descriptions that one would find in articles on the topic, which makes it extremely valuable for anyone who wants to really get a rich and thorough understanding of GraphQL. The first sentence of the October 2021 Edition of the specification provides a great high level definition,
…a query language and execution engine originally created at Facebook in 2012 for describing the capabilities and requirements of data models for client-server applications.
A few things outside of the spec you’ll read often is, “GraphQL is a query language similar to SQL”, which is true, but not. I’ve even seen descriptions like “GraphQL is a programming language” which is a hard no. Taking the specification description provides clarity around some of these simplified definitions that could leave one confused.
GraphQL, as defined, is not a programming language and not capable of arbitrary computation. This is important to note, as many of the platforms and services that provide GraphQL APIs could lead one to think that GraphQL is providing much of the functionality in these platforms, when really it is merely the facade and presentation via API of the capabilities of the underlying systems and platforms (re: Hasura, AppSync, Astra, Atlas, Dgraph, Contentful, GraphCMS, etc).
Enough about what GraphQL isn’t per the spec, what does define GraphQL? Reading the design principles behind the specification provide a much clearer idea of what GraphQL is intended to do.
- Product-centric — The idea behind GraphQL is focused on the product first. With emphasis around what the user interface, and specifically the front-end engineers, want and need for display and interaction with an application’s data. Extending this it behooves one to design GraphQL APIs around data storage mechanisms that encourage this type of user interface first, and arguably even user experience first design practices. This often includes databases like Dynamo DB, Apache Cassandra, or AWS Neptune as systems that necessitate designing from the front end into the data. Where as it draws conflicts on those that try to follow tightly coupled database first design practices with systems like relational databases. However, that identified as a characteristic, note that it doesn’t preclude design first practices — like GraphQL is designed for — with databases like relational databases. It just provides an avenue of conflict for those that want data first design since that is an entrenched practice with relational databases.
- Hierarchical — GraphQL is oriented toward the creation of and manipulation of hierarchical views. So much that GraphQL requests are structured as such.
- Strong-typing — Every GraphQL service defines an application-specific type system and requests are made in that context. This design principle is also why one will find regular use of TypeScript with GraphQL, specifically in the JavaScript web world. The two are matched very well to manage and extend strong-types to the systems using the GraphQL API. This also extends well, albeit with more mapping specifics needed to ensure types match. This design principle provides a solid level of type safety for GraphQL use within application development.
- Client-specified response — Based on this design pattern GraphQL provides a published capability for how clients will, or can, access the API. These requests provide field-level granularity. With that provided, the client can then provide exactly what it needs to retrieve from this field-level granularity. This particular characteristic is what gives GraphQL it’s famed
- Introspective — The ability to introspect against an API and derive what is available, and in many cases derive how or what to do with what is available, is a very powerful feature of GraphQL APIs. All of the intricate power of SOA Architectures without the conflagrations of XML, SOAP, and WSDLs. Arguably, one could say that GraphQL is SOA right? Ok, getting off in the weeds here, let’s keep rolling!
Language
Clients accessing the GraphQL API use the GraphQL Query Language. These requests are referred to as documents. These documents can contain one of the operations available from a GraphQL API: queries, mutations, or subscription, as well as fragments that allow for various data requirements reuse.
The GraphQL document follows a particular processing paradigm. First the document is converted into tokens and ignored tokens. This is done scanning left to right, repeatedly taking the next possible sequence of code-points allowed by the lexical grammar as the next token. This produces the AST (Abstract Syntax Tree). There are other specifics to how the document is processed, but from a usage perspective the primary paradigm of tokens, ignored tokens, and processing order are sometimes helpful to know about the processing of the GraphQL Document.
So far, this covers sections 1 and the start of section 2. The other parts of section 2.x cover a wide range of what the document can use and be made of from a source text perspective, which Unicode characters, that it needs to be Unicode, can have and utilizes white space and line terminators to improve legibility, and other characteristics that can be assumed, since almost every text formatted document type in the industry uses this today.
2.1.4 covers comments, which are important to note that the comment character is the #
sign. 2.1.5 describes the role of insignificant commas, those that provide readability such as stylistic use of either trailing commas or line terminators as list delimiters.
2.1.6 is about Lexical Tokens, where we get into one of the two key elements of the overall GraphQL document. A Lexical Token is made up of several kinds of indivisible lexical grammar. These tokens can be separated by Ignored Tokens. The Lexical Tokens consist of the following:
Token :: Punctuator Name InValue FloatValue StringValue
2.1.7 is about Ignored Tokens, the element that can be used to improve readability and separated between Lexical Tokens. Ignored Tokens are Unicode BOM, white space, line terminator, comments, or comma.
Within a token, there are punctuators, made up of one the following:
! $ & ( ) … : = @ [ ] { | }
Names in 2.1.9 are defined as alphanumeric characters and the underscore. These are case-sensitive letters thus word
, Word
, and WORD
are entirely different names.
The next key element of the language are the Operations (defined in 2.3). There are three specific operations:
- query
- mutation
- subscription
An example, inclusive of additional tokens would look something like this.
mutation {
getThisWidget(widgetId: 666) {
widget {
widgetValues
}
}
}
A special case is shorthand, provided for the query operation. In this case, if the only operation in a GraphQL Document is a query, the query operation keyword can be left out. So an example would be that this
query {
widget {
widgetValues
}
}
would end up looking like this.
{
widget {
widgetValues
}
}
In 2.4 Selection Sets are an extremely important part of GraphQL, fundamentally key, and I’ve continued writing about them at the blog entry here, that handles the code formatting and other characteristics in a vastly superior way.
That rest of the GraphQL section 1 and 2 notes are available at my blog Composite Code. I’ll have section 3 notes real soon on schema design and more.