Before we dive into the Architecture of a typical WunderGraph application, let's first explain how development usually looks like.
WunderGraph is configured using the WunderGraph SDK. Initializing a new WunderGraph project is usually done by running
wunderctl up. If you're wondering, wunderctl is the WunderGraph Command Line Interface.
One artifact of running
wunderctl up is the API Gateway configuration, which is generated into the
wunderctl up will not just start the process to continuously generate the API Gateway configuration, but it also starts the WunderGraph Server / WunderNode in parallel. When using
up, the WunderGraph Server will automatically pick up configuration changes.
The second artifact of running
wunderctl up is the generated client. You can configure which template to use in the
wundergraph.config.ts file. Templates are available, e.g. for TypeScript, React, Go, and many more...
Explaining the Architecture of WunderGraph
Now that we've got a basic understanding of how the framework works, let's talk about the components a bit more.
The WunderGraph Server / WunderNode
The WunderGraph Server is the heart of the WunderGraph framework. It's the API Gateway of the stack and written in Golang / Go. The Gateway is highly optimized for performance and scalability.
When starting the WunderGraph server, it will use our GraphQL to JSON RPC compiler and turn all the GraphQL Operations you've defined into JSON RPC calls. All of this happens at deployment time, so we're actually removing GraphQL from the runtime at all.
When you're running in production, the Gateway is handling requests by calling the pre-compiled, pre-optimized JSON RPC calls. All aspects like lexing, parsing and validating GraphQL Operations is handled during the deployment, not during the request execution.
Architecting WunderGraph this way makes it very efficient and secure. It's possible because we realized that GraphQL Operations usually don't change at runtime. So, if we're not changing Operations at runtime, we can turn GraphQL into a compile-time problem, removing it from the runtime entirely.
Next, we'll talk about the custom hooks that are available in WunderGraph. When onboarding our first customers, we've realized that it's important to them to be able to customize the API Gateway logic.
Typical use cases are:
- signing requests to specific origins
- generating one-off auth tokens and injecting them into the request
- mapping requests
- calling external APIs to validate the user's credentials
We wanted to have a solution that feels "native" and doesn't require any additional steps for the user (developer). Additionally, we wanted to have a solution that will be accepted by the majority of the developers.
Another useful hook is the
mutatingPreResolve hook, which allows you to modify the request before it is resolved.
When you scaffold a new project, you'll find a
wundergraph.server.ts file in the
.wundergraph directory. This file is the entrypoint to extend the WunderGraph server.
wunderctl up, this file gets automatically bundled using
esbuild, and executed using Node.js.
Behind the scenes, we're running a fastify server to run the hooks. Whenever you make a change to the
wundergraph.server.ts file, esbuild will re-compile the bundle and restart the server. We've invested heavily to make this as fast and easy to use as possible.
The Virtual Graph
The Virtual Graph is generated using the WunderGraph SDK in combination with running
wunderctl up. This will automatically introspect all the API Dependencies and generate the Virtual Graph. Alongside the GraphQL Schema, the process is also generating the
If you'd like to learn more about this topic, check out the docs on managing API dependencies explicitly.
The WunderGraph Client
Now that we've covered the backend part, let's talk about the client.
WunderGraph is not just a framework to generate an API Gateway / Backend for Frontend (BFF). We also generate clients from the same configuration, giving you a full end-to-end solution, with no additional tools required.
As you've learned, all configuration happens in the
wundergraph.config.ts file. Alongside the backend configuration, you're also able to define what templates to use to generate the client.
One good example of how a client could look like is TypeScript and Next.js. As our monorepo is open source, all templates are available for you to use, and you can easily create your own.
The generated client is based on the WunderGraph RPC Protocol. This protocol defines how WunderGraph server and the generated client communicate.
For React and Next.js, we've also added a separate package to generate hooks with support for Server Side Rendering (SSR) out of the box.
Summary - putting it all together
The WunderGraph SDK is responsible to configure your application. The file
wundergraph.config.ts is the main entrypoint for the configuration. For customization of the server, you can use
Once you run
wunderctl up, your WunderGraph server is up and running, behind the scenes, we're generating the configuration for the API Gateway and the client.
If a client wants to execute an Operation, it calls an Endpoint on the API Gateway, which will then execute the pre-compiled Operation against the Virtual Graph. Both, request and response can be manipulated using hooks.
If you'd like to learn more about the execution flow of a request, check out the docs on the request lifecycle.