My name is Jens, and I'm the Founder & CEO of WunderGraph, but most importantly, I'm a Developer, I always was, and still am. WunderGraph is a small but growing team, and as of today, I'm still working on the product. So, what I'm telling you is not from the perspective of a CEO, but from the perspective of a Developer.
WunderGraph and Apollo share similar goals, but the approach is different, which can be described by the history of the two. Let's have a look at the two.
Apollo, successor to Meteor, the "best way" to build with GraphQL
Geoff Schmidt, the CEO of Apollo describes Apollo as the successor to Meteor.
Apollo began life as the Meteor 2 data system, designed from all of the learnings from Livedata, which ultimately could be summarized as: there needed to be an abstraction layer in between the client and the server, rather than embedding MongoDB queries in the client. --- Geoff Schmidt, CEO Apollo
Meteor ran into the limitations of tightly coupling the client and the server. Interestingly, we can see this pattern repeat itself, with solutions that generated a GraphQL API from the Database, and expose it to the client.
So, the idea behind Apollo is to create an abstraction layer between client and server. Additionally, Apollo introduced the concept of the Supergraph, the idea to implement a Graph in a distributed way. This can also be found in their headline:
The best way to [build with,manage,scale] GraphQL
It's all about helping companies to build GraphQL APIs.
WunderGraph, a new way to think about APIs, leveraging GraphQL
The history of WunderGraph is different. I've worked in Enterprise Software Development for a while and realised that there's a huge problem with API composition & development. We've spent huge amounts of time on composing APIs of different protocols, transports, and so on.
Early on, I've had the idea that it should be possible to query every system using GraphQL, removing the overhead of having to write manual code to mediate protocols and implementations.
While I was working on the solution, a GraphQL Engine to automatically mediate between a GraphQL layer and the underlying systems, I've realized that my thinking was wrong and limiting. We don't need more abstractions. We don't need better ways to build GraphQL APIs. In fact, the goal shouldn't be to build GraphQL APIs. My understanding of APIs was wrong.
The idea of using GraphQL as the language for API composition is great, but we need to get rid of the "Server-full" thinking.
Understanding APIs as dependencies makes Composition & Integration 10x easier
What I was lacking was the idea of understanding APIs as dependencies. Let me explain this a bit more in depth.
The traditional, Apollo-way of adding another internal or external API or database to a system is to extend "THE Graph". However, I've realized that the number of APIs is only growing, and so we'd have to continuously extend our Graphs with every new API we'd like to use. There needs to be a better way to build a system that can handle an exponentially growing number of APIs.
We can borrow the solution from existing programming paradigms, it's called "dependency management" or, more well known, "package management". If you need another "package", you can
npm install or
go get it. The package manager manages the dependencies of you project and helps you to update them.
Now, APIs are not code. You can't just "add an API" to your application. It's a lot more complicated than that.
GraphQL as the language for API composition
The Apollo-way is to build Subgraphs and compose them into a Supergraph. If an application needs to use multiple APIs, it talks to the Supergraph. That's what I call "API-full".
WunderGraph takes a different approach. We don't build one monolithic Supergraph. We also don't have to adopt GraphQL and Subgraphs all across the organization. In fact, WunderGraph embraces diversity in API styles. WunderGraph can compose APIs of different styles, like REST, GraphQL, Apollo Federation (Subgraphs and Supergraphs), gRPC, Kafka, PostgreSQL, MySQL, MongoDB, etc...
But instead of building a single, monolithic API, WunderGraph allows you to build a unique composition for each application. That's the whole point of "package management".
In an exponentially growing system of APIs, you will eventually run out of resources to connect to "gigantic" Supergraphs. It's the same with npm. You only install the packages you need, otherwise your node_modules folder would grow beyond the limits of your system.
In more technical terms, WunderGraph allows you to compose multiple API dependencies into a single unified Graph with just a few lines of code.
And that's how we've created an API composition for our application, combining a weather and a countries API. If we now define our GraphQL Operations, WunderGraph generates an API Gateway for us that "executes" our API composition.
To expose or not to expose GraphQL APIs
How we expose APIs is another topic which distinguishes WunderGraph from Apollo. Apollo, by default, exposes your GraphQL APIs over HTTP. You will then have to add additional 3rd party libraries to lock this API down, add authentication, authorization, and so on. So, their approach is to give the user a very basic server implementation and leave security to the user.
The WunderGraph approach is to never expose a GraphQL API at all, and manage all aspects, from security to authentication, authorization and caching out of the box. We provide an end-to-end solution that implements OWASP recommendations by default . WunderGraph is locked-down from the beginning, you don't have to add any additional libraries or modules.
WunderGraph does out of the box:
- Input Validation using JSON-Schema
- Injection Prevention / Process Validation (at compile time)
- Query Limiting (Depth), Query Cost Analysis (at compile time)
- Server-side batching and caching
- Access Control protection with RBAC and ABAC
- mitigates batching attacks
- prevents introspection attacks
With Apollo, you're responsible to handle the security of your GraphQL APIs on your own. But should you really be focussing on security, or is this a framework concern, and you should focus on the application itself?
Interestingly, in the beginning, Geoff was hesitant to allow clients to send arbitrary queries to the server.
Similarly, and also to accommodate larger and more complex apps, we would move UI component data dependency specification from the backend (a DDP "publication") into the UI components, by letting the frontend send a query over the wire to the backend. The reason we didn't do this in the first place was security—I thought it would be hard to convince people to use Meteor if the client was sending arbitrary clients to the server. --- Geoff Schmidt, CEO Apollo
It seems that they've dropped these concerns in favour of adoption. But as you will see, doing the right thing security-wise doesn't have to come with a lot of effort.
Comparing the WunderGraph Developer Workflow with Apollo's
To make this work, we've developed the WunderGraph Compiler and Runtime, which takes the API composition and Operations as input, and compiles them into a JSON-RPC API, while also generating a type-safe client for ease of use.
Let's break down the flow:
- Add API dependencies to your project
- define GraphQL Operations
- WunderGraph generates a JSON-RPC API and a type-safe client
- Deploy Serverless API Gateway alongside your Frontend
Now let's compare this flow with Apollo:
- Wrap all "API dependencies" in Subgraph
- Compose the Subgraphs
- Deploy the Supergraph
- Add Apollo client to your Frontend
- Define GraphQL Operations
- Lock down the API, add authentication, authorization, caching, and so on via additional extensions
The development workflow is quite similar, but the WunderGraph Architecture comes with a lot more batteries included.
Will GraphQL take over the world of APIs or will there be a variety of API styles?
Another question to ask is whether it's a scalable model that all APIs must be exposed as Subgraphs and composed into a Supergraph. Especially when it comes to cross-company API integration, I don't believe that all companies will adopt GraphQL. Ideally, a solution will allow for incremental adoption. You should be able to compose APIs of different API styles, not just Subgraphs.
Another question is if we should build systems with a single API style, GraphQL, or if we should embrace a variety of styles, like REST, gRPC, or even event-driven architecture with Kafka.
With the Apollo approach, you always have to add your APIs as Subgraphs to "THE Graph". The WunderGraph philosophy is to allow different API styles, but use GraphQL as a "meta-API" style to compose them virtually.
On the surface, you might be consuming a subscription from a Microservice. But behind the scenes, the Subscription is actually powered by Kafka. Need to post a message to a Kafka topic? Make a mutation. But you don't have to build a Subgraph for that, and go through the hoops of adding it to the Supergraph, deploying it, and adding a client to your Frontend.
Do you think in Graphs, or in API dependencies? Should you have a single monolithic Supergraph, or small, lightweight API compositions per application, deployed on "Serverless" API Gateways? Should we adopt "THE Graph" for all our APIs, or use GraphQL as a "meta-API" style to compose a variety of API styles? Is it easier to achieve incremental adoption with a GraphQL-only model, or by using GraphQL only virtually, leaving existing systems as is?
Ask yourself which model is best for your organization today, but also allows you to scale in the future. Do you believe in exponential growth of APIs, like we do, or do you think all APIs can be rewritten as Subgraphs.
Our goal is to build the GitHub for APIs. We want to enable new ways of collaboration between API providers and consumers. We believe, the API era has only just begun, and will be fueled by the idea of "API dependencies". GitHub and Open Source brought together developers to build and collaborate on common solutions, allowing for re-usability and composition.
There's barely any npm package without dependencies. You never have to start from scratch, but can build on top of existing packages. With APIs, we're really just starting to enable this kind of collaboration.
The solution is not the Supergraph. It's on-demand composition of any API style, and a model of collaboration that is similar to GitHub, like issues when there's a problem with an API dependency, discussions to propose and discuss API changes, watchers to get notified of API changes, and so on.
Bonus - Licensing, Open Source and Performance
While I tried to focus on Architecture and Developer Workflow, there are a few other things I'd like to point out.
WunderGraph supports Apollo Federation out of the box, not just the Subgraph implementation, but it's actually possible to use WunderGraph as an Apollo Federation Gateway replacement. Our approach to GraphQL doesn't just make Federation a lot more secure, but is also very efficient, as our benchmarks show.
That said, our Gateway is not just super fast and secure, it's also truly open source. Apollo re-licensed their Federation implementation using the Elastic 2.0 license, while WunderGraph is licensed under the Apache 2.0 license. The GraphQL Engine of WunderGraph is licensed under the MIT license.
This means, no other company is allowed to use Apollo's implementation to provide a hosted GraphQL Gateway, while this is possible with WunderGraph.
In fact, the WunderGraph Federation implementation is a separate package (graphql-go-tools ) which is MIT licensed, and it's being commercially used by many other companies. We're even collaborating with some of them actively to maintain and improve it. The Elastic 2.0 license works against such collaborative efforts as really only a single company benefits from it.