Editor’s Note: This post was originally published in January 2019 and has been updated in September 2020.
No other language manifests Edsger Djikstra notion of brevity without jargon better than GraphQL. This is a querying language that has proven its worth by its simplicity and effortlessness. As I was exploring the capabilities of this querying language, I was quick to realize its potential in its main use as an API building tool. I also realized that its benefits are greatly underrated, and thus made it my aim with this piece to stress the advantages of GraphQL as well as introduce its importance in the realm of serverless which is greatly aided by AWS AppSync.
AWS AppSync itself is a powerful application development service that allows you to create services using GraphQL. It truly does justice to the abilities of GraphQL and after personally using it to build a simple API, I can not imagine developing API’s with a serverless framework in any other way. Released in 2017, AppSync has several features that ease the use of GraphQL, and again, I strongly feel that the value of these features is greatly underrated or simply not known due to the novelty of the service.
Therefore, considering the applications of AWS AppSync and its GraphQL support, I would not like to present a tutorial but rather an informative piece highlighting some of the many benefits that the ecosystem of software can gain by using AWS AppSync.
Before we dive into AppSync, we must first understand what GraphQL exactly is. What is this language whose beauty and power I have been incessantly ranting about for so long now? Well, GraphQL is basically a syntax that allows you to define what data you exactly need. It has three major components which include:
- Schemas, which are the definitions of all operations
- Data Sources, from where the data is queried
- Resolvers, which act as connecting blocks between the schema operations and data sources.
The structure of GraphQL thus makes it client-specific and thus allows the client to decide the data it needs instead of being bombarded with all kinds of data, irrespective of its relevance. This also leads to a substantial reduction of endpoints needed when building your API.
As a result, the main benefits of GraphQL are as follows:
Refined Data Retrieval
GraphQL solves the problem of overfetching and underfetching and instead returns the exact data that is specified. A nice example of manipulating data with GraphQL can be seen here. Instead of making additional calls to retrieve each
animal entity related to the
reserve entity, GraphQL conducts the query in a single request. Moreover, the data returned is exactly as is defined, so for example, if we only wanted the list of animals in the animal reserve and not the area size of the animal reserve, the returned result would not contain the area size and hence make querying for data overall more efficient. This can also be seen to give more control to the client, allowing it to dictate exactly what data is required and how it is required.
Due to the GraphQL schema, the operations to be performed are defined comprehensively, all the way from the inputs to expected to the possible outputs. The strongly typed attribute of GraphQL schemas, in turn, ushers a wider range of benefits for developers such as making it easier to validate API requests, autocomplete in IDEs, and auto-generation of API docs. As a result, the entire system attains a more pulchritudinous form allowing better understanding and ease of development, something not fully conceivable with traditional API development methods.
Since the way we perform operational requests to a GraphQL API necessitates defining the data returned, developers know exactly what the structure of the returned result is. Moreover, when we describe the GraphQL schema, we state the datatypes of all the fields used in the API operations and thus know what type of data is expected. All of this information aids in the development and use of the API, resulting in a more efficient and productive product building.
Apart from the three benefits listed above, there are countless other advantages that I love and have personally gained with GraphQL. As much as I would like to list them all, there are only so many words I can write before I lose you to a random cat video. Ergo, I strongly urge everyone intending to build data-driven applications to checkout GraphQL to experience its simplicity and power firsthand.
On the 13th of April 2018, AWS made AWS AppSync generally available (GA), ushering in an era of improved GraphQL support. As I already discussed, the exceptional benefits of GraphQL endorse its use in the field of data-driven development and hence with AppSync, AWS has managed to make GraphQL development incredibly easy and accessible. AppSync has proven effective as a development tool due to its powerful features and simple set-up, the two qualities of every developer's dream tool.
AWS describes AWS AppSync as a “serverless back-end for mobile, web, and enterprise applications”. Considering the pure definition, Amazon has continuously released features over the past years to facilitate AWS AppSync’s role as a serverless service for data-driven applications. So let us take a look at some of the most basic and advanced capabilities of the solution, making it a tool worth considering for the journey towards a GraphQL application.
Effortless Development with Code Gen.
The folks at AWS have put a lot of stress on making development with AppSync child’s play, and this is apparent with the code generation capabilities that AppSync provides. This involves acquiring automatically generated schemas and resolvers, mitigating the pains of having to define even the simplest of operations manually.
Automatic code generation is offered in two forms. One of them can be done via the AppSync Management console and the other is done using the AWS Amplify CLI.
The AWS management console provides several opportunities for you to benefit from the automatic code generation feature. For example, when creating a data source, you can choose to create a DynamoDB data source automatically which will also give you the option to generate automatic schema code. Similarly, you can also use the aided API building option which comes up as you start the development of your application.
Similarly, you can generate schema code and even resolvers using the AWS Amplify CLI.
The end result is an automatically generated API with all client-side operations already present and ready for use. This truly is a boon for developers as it allows for faster code development and a more structured approach to building data-driven applications.
AWS Cloud Formation allows you to manage your AWS stack and manage your AWS resources via templates. The way it is used is you defining the resources you would like in a YAML or JSON file and by deploying the service either using serverless or through the CloudFormation console, AWS generates the resources and makes them ready for use as you specified.
Cloud Formation templates now support AppSync and hence setting up your data-driven application architecture has now become easier. This means that schema operations, data sources and the resolvers to connect them can all be defined using the Cloud Formation template. To learn how to do so, please follow the tutorial here.
Fine-Grained Authorization and Access
Fine-grained access means controlling the manner in which data can be read or written depending on the authorizations that the clients possess. This allows you to define various security configurations for different data resources according to user identity, conditions, and data injections. Hence providing flexibility in how the data sources within your AWS are managed.
The way this is possible is thanks to the fact that AppSync adds user and role information into the GraphQL request as a context object. This object can then be accessed by the resolver to grant permissions within the resolver logic. Deciding whether or not to give permissions is as easy as writing a single
if statement. More complex authorization logic can obviously be written, and to fully understand how to do so, you may refer to the AWS documentation here.
Direct Lambda Resolvers
One of the more recent, and definitely more impactful improvements in the capability of using Lambda functions as resolvers. This allows the user to overcome the barrier of defining Apache’s Velocity Template Language (VTL) resolvers in your GraphQL application infrastructure.
As mentioned, resolvers translate GraphQL requests into a format that is comprehensible by the connected data source and conversely translate the response. These resolvers were built using VTL which meant the overhead of implementing in VTL, regardless of its countless benefits.
This is where the new improvement in AWS AppSync proves beneficial, allowing users to use AWS Lambda functions directly as resolvers. Developers now have the choice to bypass the need for VTL resolvers, setting up AWS Lambda functions to handle the mapping of requests between clients and the connected data sources. In fact, developers can also apply hybrid solutions if needed, deploying a combination of VTL and AWS Lambda based resolvers where seen fit.
Resolvers are executed by AWS AppSync requests and responses on GraqphQL fields with the usual purpose being the mapping of these requests and responses to the fields. With Pipeline Resolvers, these executions can mean having multiple operations triggered by one GraphQL field execution, implemented as a separate sequential “functions” within the resolver’s pipeline.
When using Resolver Pipelines, each resolver consists of ‘Before’ and ‘After’ mapping templates alongside a list of functions. Each function, in turn, possesses request and response mapping templates that manage the interaction of a single data source. Therefore stacking different functions in the right order allows you to perform more complex resolver operations.
As a result, one of the major benefits of Pipeline resolvers is to enable interaction with various data sources in one field execution. Each function theoretically manages the interaction with a separate data source. Another use-case that is also enabled is performing authorization checks, validation, and other such operations prior to the actual mapping of requests and responses to the GraphQL fields, all under the scope of a single resolver.
Therefore, considering the benefits of GraphQL coupled with the features of AppSync, I truly believe that Amazon has revolutionized the way data-driven applications are being developed.There are obviously pros and cons to the case, but we have seen AWS AppSync evolving over the years to overcome the various barriers in implementing GraphQL applications. As a result, it must be acknowledged that the list of capabilities listed in this piece is not an exhaustive one. AWS AppSync has been continuously improving to further ease the developer experience, and there is no doubt that we will see much more powerful capabilities of the tool coming out soon.