wundergraph

GraphQL Federation

WunderGraph is the most powerful GraphQL Federation service on the market, period.

GraphQL Federation is the concept of automatically merging GraphQL microservices to form a unified GraphQL schema.

TLDR

If you want Apollo Federation with subscriptions, support for the @defer & @stream directives, superior performance and security, then WunderGraph is your solution!

I want to see it in action!

You can jump to the demo straight away! However, if you prefer reading just skip the video for the moment.


Are you excited?

If you're interested in trying it out, sign up with our Federation Early Access Programme to be the first in line when it's ready to be used.

Available languages

Currently, GraphQL Federation is implemented by several languages and frameworks:

Go, Java, Kotlin, PHP, Python, Scala, Ruby, Rust

How to?

Simply replace the Apollo Gateway with a WunderNode, this is how we call our gateway, and give it the URLs of all federated services.

Benefits

Using GraphQL Federation with WunderGraph get's you more than just a federated Gateway. WunderGraph gives you the features you asked for plus better performance and security than similar products.

Subscriptions

One of the most requested features for Apollo Federation is adding support for subscriptions. We're not just giving you this feature as a simple drop-in. We also make subscriptions horizontally scalable!

If 10.000 users connect to a WunderNode to consume the same subscription, there would still be only one single subscription to the upstream GraphQL server.

subscription UpdatedPrice {
# resolved by the Products service
updatedPrice {
upc
price
reviews {
# resolved by the Reviews service
body
author {
id
# resolved by the Accounts service
username
}
}
}
}

Support for the @stream directive

Loading long lists can take time, especially in a federated environment where multiple requests are needed to fetch a list item. In the scenario below, the WunderNode will immediately return the "id" field and then stream each review object.

query UserReviews {
me {
id
# each review item get's streamed one by one
reviews @stream {
body
author {
id
username
}
}
}
}

But there's more to it! Ideally, you want to be able to render above the fold as soon as possible. To improve this even further we allow you to define the initial batch size:

query UserReviews {
me {
id
# initially we'll send up to 10 review objects and then stream the rest
reviews @stream(initialBatchSize: 10) {
body
author {
id
username
}
}
}
}

Let's assume you need at least 10 reviews to have enough data to render the user interface above the fold. With the initialBatchSize set to 10, we can achieve exactly this. As a result, we achieve a superior user experience with just one small annotation.

Support for the @defer directive

In a federated Graph, you usually have to wait for the slowest service to answer a request until you can send the first byte to the end-user. With the @defer directive we can easily improve this situation.

In this example, we assume that loading the author would result in a very expensive and time-consuming call to the Accounts service. We can simply annotate the field with @defer so it gets streamed in once the Accounts service responds.

query TopProducts {
topProducts {
upc
name
price
reviews {
body
# author will be streamed in once it's available
author @defer {
id
username
}
}
}
}

Stream data as it gets available

There are literally no limitations on how you can use @defer and @stream. You can mix and nest them however you want. Our execution engine is designed in a way to stream data very efficiently without much overhead.

query TopProducts {
# top products get streamed one by one from the start
topProducts @stream {
upc
name
price
# reviews get streamed as well
reviews @stream {
body
# as the author field is expensive it get's streamed in with a subsequent flush
author @defer {
id
username
}
}
}
}

How Streaming works

Streams in WunderGraph are very easy to understand!

The very first response looks like a standard GraphQL response. All subsequent changes get streamed in by the WunderNode as JSON-Patch Objects.

There are two simple reasons why we chose JSON-Patch as a solution instead of sending additional GraphQL objects with path information, as proposed by others.

First, JSON-Patch is widely adopted by many programming languages including JavaScript for the browser. So all the browser has to do is use one of the JSON-Patch implementations and merge the path into the previous object.

Second, we discovered that sending patches one by one adds severe overhead to the client as each message needs to be processed on the individual base. It's a lot more efficient to process messages in batches. To make this very easy to use we opted for a flush-based approach.

We batch all patches together up until the end of the current flushInterval.

To flush or not to flush

Depending on your use-case you might want to flush more or less frequent.

E.g. if you're sending very little data but want to be very fast you can set the flushInterval at a lower number.

If you have an operation where you expect lots of changes being streamed, e.g. very long lists, you can set the flushInterval to a higher number to achieve larger batch sizes.

query TopProducts @flushInterval(milliSeconds: 500) {
topProducts @stream {
upc
name
price
}
}

One more thing

So far, this was all about Federation. But there's one important thing to add here.

You can build a Federated Graph with WunderGraph even if your services don't support the GraphQL Federation Spec. You can also add REST APIs to the Graph as we can automatically turn any REST API into a GraphQL API. With our Link-Builder, we're able to add connections between services without changing them.

In the future, we're planning to add more connectors so you can add any service to your Graph, e.g. Kafka, RabbitMQ, Nats, AMQP, SOAP, etc..

Are you excited?

If you're interested in trying it out, sign up with our Federation Early Access Programme to be the first in line when it's ready to be used.