“The original idea of the web was that it should be a collaborative space where you can communicate through sharing information”
— Tim Berners Lee (Inventor of Web)
All software developers have to deal with fundamental requirement of data communication — how to access data from remote source? Typically on client side an application wants to access data from backend service. But on server side one service might want to access data from other services — think of micro-services communication within the system or communication to external services (e.g. AWS or other managed services). So how we deal with that? Well, most commonly we use a fundamental application protocol for Web called HTTP. It allows us to communicate in request/response manner. What if we want to access data in real-time manner? Then we can use Web Sockets which allows both client and server to send data messages to each other at any time, so we can emulate publish/subscribe communication to get real time updates and notifications.
Both HTTP & Web Sockets are most commonly used protocols for data communication in our apps and services. They are different protocols but they have one thing in common — we can send/receive any type of data. There are no guarantees that the data we send or receive conforms to certain structure. We might send partial data or data in wrong format which results in errors. So how can we know what are the possible ways/routes to send/receive data? Whats the structure/specification of each? What data is expected in which format for a certain route and how to ensure that data being sent conforms to that structure and there are really no errors? We typically use documentation to describe all these structural details and manually verify the structural correctness of data in our codes before actual processing. Since both client and server have to agree on the contract at interface level (shared boundary for information exchange). Having implicit & loose contract leads to uncertainty and bugs thus making it harder for systems to communicate reliably.
GraphQL concretely defines the data interface contract between service and its consumer in declarative language.
Basically GraphQL provides a complete and understandable description of the data and its related operations available in service in the form of schema which includes the following:
Entities with attributes and their relationships with other entities.
Queries to fetch data
Mutations to create, update & delete data
Subscriptions to get real time updates
GraphQL makes use of type system to describe whole data model of service and all operations that could be performed by service consumer. We can think of GraphQL as a query language for Web APIs exposed by the backend services.
This comprehensive schema defintion enables GraphQL to have some really neat benefits for data communication in our apps and services.
We can specify the exact data requirements and GraphQL fulfills all in one request. Consumer is completely in control of what the server should send back. There is no need for extra round trips to the service and still being left with either less or more data then we need. This means efficient utilization of precious network resources.
No more reading/writing of potentially vague and incomplete documentation about Web APIs. GraphQL schema serves as concrete and most up-to date form of documentation for service consumers. Strongly typed API schema means we can validate API calls as we type. Also it eliminates lot of boilerplate in codes for data validation. We can confidently ensure that each data field is of certain type and whether it can be null or not. This enables more productive & less error prone development experience for both client and server side.
GraphQL has built in support for real time updates. We can access data in both request/response and publish/subscribe manner in one unified language. No more switching to different types of protocols for accessing data at rest or data in motion. GraphQL abstracts away the underlying low level application protocols (HTTP & Web Sockets).
We can use any storage mechanism with GraphQL since its about putting schema at front of data interface (API layer). So GraphQL API does not really cares about the source of data. We can use files, databases, external APIs or even existing backends. GraphQL really shines in combining different data sources into one neat API. Also we can use any language on backend for creating GraphQL server and integrate with any client (mobile, web & desktop) app. This means** anyone can adopt GraphQL quite easily regardless of technology stack and architecture.**
GraphQL is an open specification and there are multiple open source client/server implementations by different companies. The ecosystem is thriving with open source tools and growing community. Few tools and services worth mentioning are:
AppSync is serverless & highly scalable GraphQL based managed service from Amazon.
Prisma is GraphQL based ORM for Databases.