Often when creating a full-stack application, a lot of time is consumed by back-end development — usually more than expected.
Querying for data must be specific, which typically means some excess or deficit of the data we need when interacting with a RESTful API. This can further impact user experience and app performance due to excess overhead introduced by inefficient requests when deployed at scale.
It would be great if we didn't have to delicately tip toe through our data or pull down heavy chunks just to retrieve or update specific information.
Luckily, a technology was designed for that very purpose and its name is GraphQL
. Today we will review the potential it has for our next projects from the perspective of a curious novice.
Concise Questions Within Detailed Data
GraphQL is an open-source querying language developed by Facebook that was released in 2015. Its primary premise is to provide a way for client-side requests to ask concise questions about the data in your API.
- Only What You Need
One of the best aspects of implementing GraphQL is that you can retrieve or update only the information you want to interact with while retaining freedom in how your data store is structured.
- Data Typing
Another terrific addition to workflow is the stronger typing of data that is sent and received through GraphQL, complete with debugging tools that make development easier overall.
- Database Agnostic
The fact that GraphQL can be used with both relational and non-relational databases, such as PostgreSQL
and MongoDB
, among others, is definitely a plus not to be overlooked.
Not a Middleware
In practice, GraphQL essentially acts as a form of translator for your database, whereby client-side communication is relayed through it rather than passed to your data store directly.
In the short term, this adds a layer of planning to a project that requires time to be allocated for design of requests themselves. However, the intuitive syntax affords a greater degree of freedom, faster turn around, and more accurate debugging when taking the long view.
To put it simply, the added value in workflow alone more than makes up for the time taken to implement it.
Let's take a closer look at the overview of how GraphQL is structured to get a better sense of what it does.
Services
All data returned through GraphQL are effectively requested values that correspond to keys that match specific fields. These keys and values exist on a special "root" object that is used to pass data to the client.
Services can be written in any language, allowing for seamless integration on your server — even if your app has already been deployed.
The way that GraphQL interacts with data is through services
, defined as blocks comprised of a data type
that contains one or more fields
. Those types and fields are then associated with callback functions that are used to process information. For example, the following structure:
type Query {
opponent: Player
}
type Player {
id: ID!
name: String!
}
function Query_opponent(request) {
return request.auth.player;
}
function Player_name(player) {
return player.getName();
}
To run the above code, the request would take the following form:
{
opponent {
name
}
}
While the syntax looks similar to JSON
, it is important to note that the above GraphQL syntax is written in multi-line string format, typically surrounded by back-ticks (also known as "grave diacritics"), and must be parsed during translation by the included server runtime.
There are many topics involved in the definition and use of GraphQL and the rabbit holes can go rather deep.
For now, we are most interested in taking a broad overview of the main building blocks. Let's start with Queries and Mutations.
Queries and Mutations
Queries are GET
requests written more intuitively and executed more dynamically using GraphQL. Conversely, Mutations are effectively POST
, PUT
, or PATCH
requests.
To that end, all requests made through GraphQL are functionally no different from less efficient RESTful requests, in principle. However, GraphQL makes it possible to embed conditionals into requests themselves, as well as aggregate data more cohesively into a single return of data.
Here is an example of what a query and a mutation might look like in GraphQL:
{
hero {
name
# Queries can have comments!
friends {
name
}
}
}
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
Source: GraphQL Docs
Schemas and Types
A schema effectively operates as a rule set for GraphQL services, whereby returned data is validated using the master definition for a given service block.
Types are object types that you define to describe the properties of the data you expect to return from your server. These are the container objects used to reference a given service block where data fields are contained.
Here is an example of how you might write a schema of GraphQL object types:
schema {
query: Query
mutation: Mutation
}
query {
hero {
name
}
droid(id: "2000") {
name
}
}
Source: GraphQL Docs
Putting It Into Practice
The cursory nature of this overview is meant to give an impression of the possibilities made available by implementing GraphQL rather than an in-depth instructional walkthrough.
In order to provide a snapshot of what can be accomplished, let's skip ahead to an example of what all of the features look like when put into practice.
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
query HeroForEpisode($ep: Episode!) {
hero(episode: $ep) {
name
... on Droid {
primaryFunction
}
... on Human {
height
}
}
}
Sources:
GraphQL Docs - Directives
GraphQL Docs - Inline Fragments
A great example of how to use GraphQL in the context of MongoDB using the MERN
stack can be found in this ongoing tutorial series by Code Realm on YouTube:
Conclusion
I hope that this overview has given you an idea of what GraphQL can do in your next project and that your RESTful APIs will be more relaxing.
I look forward to writing an in-depth walkthrough once I have had a chance to utilize this technology in my next app design.
Top comments (0)