<onWebFocus />

Knowledge is only real when shared.

Thoughts on GraphQL

October 30, 2023

Is GraphQL still relevant and how will the future look like?

Both React and GraphQL emerged during the early days of the Facebook Open Source era back in 2015. However, it's important to note that while React is just one of many frontend frameworks available, GraphQL distinguishes itself as the sole client-side query language. In this article, we'll delve into whether this uniqueness suggests that GraphQL has fallen short in demonstrating its necessity when compared to alternative approaches such as tRPC, which we've discussed previously. It's evident that GraphQL's initial rapid advancement has encountered some slowdown in recent times, and the technology has yet to fully integrate with more recent developments like Serverless and TypeScript.

Evaluating the Continued Relevance of GraphQL

GraphQL came into existence during the heyday of Single Page Applications (SPAs) and the surge in client-side JavaScript development. It was primarily designed to address the challenges associated with managing complex client-side logic and data retrieval. However, the question arises whether GraphQL remains relevant for backend development, given that most databases already come equipped with their own query capabilities. Furthermore, with the recent resurgence of server-side rendering (SSR), the necessity for GraphQL has somewhat diminished. As we've discussed SSR in a previous post and witnessed the rise of Backendless approaches that simplify web and mobile development, it's wrong to assume that the demand for a client-side query language has waned.

Another factor contributing to the reduced demand for alternatives is the growing synergy between frontend and backend development. With server-side code increasingly being written in TypeScript and tools like hono, it has become more straightforward for frontend developers to adapt and work with the backend code. This reduces the dependency on a dedicated query language. However, it's important to note that while GraphQL may be less imperative in custom applications, it still holds its relevance in scenarios where content abstractions, such as payload or platforms like hasura.io, are in use. In these cases, the backend code may not be easily modifiable, making a query language a valuable tool for interacting with the data.

The Ecosystem

Within the GraphQL ecosystem, several tools and libraries have emerged to enhance its capabilities and cater to various needs:

  1. Relay relay-runtime: Facebook's Relay framework provides a versatile browser client for GraphQL. It is equipped with numerous build-time optimizations and a range of features that enable the effective use of GraphQL, especially in large-scale applications.

  2. Apollo: The Apollo suite, developed independently, is widely embraced by the community. It encompasses the @apollo/client for React and @apollo/serverfor Node.js, offering a comprehensive set of tools and solutions for GraphQL development.

  3. GraphQL Codegen: This tool offers an abstract and flexible approach to generating type definitions from a GraphQL schema endpoint, making it easier to work with strongly typed data in your applications.

  4. Mobius: Although still in its experimental phase, graphql-mobius explores the possibilities of inferring types directly within TypeScript by analyzing template literals (strings). This provides a direct way to access GraphQL types within TypeScript.

  5. Zeus: Recently gaining traction, graphql-zeus provides a typed approach for generating TypeScript queries, making it easier to work with GraphQL in a type-safe manner.

  6. Pothos: In contrast to Zeus, which is designed for the client, pothos enables the direct composition of the schema, including resolvers, using TypeScript.

  7. GQless: GQless is an intriguing plugin that auto-generates GraphQL queries based on data accessed through a Proxy during the React render cycle. While this approach appears magical, it falls short in capturing the full expressiveness of GraphQL queries. Notably, during the initial render, it relies on empty mocks, which can lead to certain issues in practice.

These diverse tools and libraries cater to different aspects of GraphQL development, allowing developers to choose the right solution for their specific use cases and preferences.

Effect of Recent Developments: TypeScript and Serverless

At the time of GraphQL's inception, TypeScript had not yet gained widespread relevance in the development landscape. While GraphQL mandates the description of data structures in a separate schema that can also be transmitted to the client, it lacks a native mechanism for automatically inferring the resulting types of a query. Fortunately, tools like GraphQL Codegen have emerged to address this issue, albeit through an additional build step.

Moreover, it's worth noting that most GraphQL servers are designed to run on Node.js, which often results in a significant size and startup time overhead. This characteristic renders them ill-suited for Edge functions, where strict constraints on size and rapid initialization are paramount, often not exceeding 1MB in size and requiring lightning-fast startups. Furthermore, essential features like authentication and permissions are notably absent in many GraphQL server implementations, necessitating manual implementation or the addition of supplementary layers, such as Hasura, to provide these critical capabilities.

Pioneering a Comprehensive Client-Side Query Solution

In the realm of backend development, various query languages, such as SQL, are available. However, many developers tend to gravitate towards Object-Relational Mapping (ORM) solutions that provide a convenient interface in the programming language they are using, like JavaScript in the context of Node.js. In contrast to this trend, when it comes to GraphQL, client-side ORM solutions have been somewhat elusive. While prisma has offered a bridge between GraphQL and databases, it primarily operates on the server-side, leaving a gap for client-side ORM tools.

To bridge this gap and streamline the process of generating GraphQL queries without manual intervention, I introduced a plugin called laval. It has proven effective for simpler applications and even features an integration with Hasura. A notable aspect is its offline support, leveraging IndexedDB. Nevertheless, it's essential to acknowledge that laval is a work in progress. Its schema parsing and query generation logic are only partially implemented, and type inference remains on the horizon, likely necessitating a manual step involving GraphQL code generation.

Considering these ongoing challenges, I've arrived at the conclusion that it might be more efficient to embark on the development of a client-side query ORM from the ground up. To that end, I have reserved the npm name epic-query. The vision is to craft a comprehensive, fully integrated solution. This new ORM should seamlessly infer types from the database schema, and by leveraging the Serverless Edge runtime, it will dynamically create PostgreSQL queries as clients transmit ORM-mapped requests directly from the client. Additionally, epic-query will have direct integration with the state management tool epic-state, which will also handle offline persistence through an IndexedDB plugin, ensuring a holistic approach to client-side GraphQL query generation and data management.

This post was revised with ChatGPT a Large Language Model.