Apr 4, 2023

Working with Bramble: How we test out breaking changes

We have been using Bramble, our federated GraphQL gateway server here at Movio for 2 years now. Our new intelligent data analytics and campaign management solution, Movio EQ uses Bramble exclusively as the API gateway through which the frontend accesses all backend services and the graph is also used in many backend service inter-communications when it follows a query/response model.

Bramble has proven to be impressively stable in production and has helped our teams work in a more cross functional manner. Designing an API between frontend and backend has been made easier with a self-documenting and extensible system.

However, having a unified API meant that putting out backwards compatible changes was becoming more difficult. Our frontend teams had come to rely on the stability of the dev environment for their work as running the full backend on a developers machine is too complicated.

The problem

We needed a way to put out an in-development or unstable version of a service alongside the mainline version of the service.

We have a number of microservices, some which require a bit of work to set up so we didn't want to have to run a complete copy of our development environment.

As Bramble is an open source project we also have a principle of not adding any Movio-specific code to the main project, so we had to solve this either using custom plugins or other parts of the deployment that are not part of the public project.

Our solution

Movio is a multi-tenanted system where we switch which customer we are referring to based on an HTTP header from the frontend requests. We realised we can switch between two different deployments of Bramble based on this header using the Canary annotations available in our NGINX Ingress Controller.

In our development environment requests made for a specific tenant can now be routed to the new bramble deployment, which has an almost identical configuration, with the exception that any services in development can be replaced with endpoints of the unstable versions.

This might sound like it adds a configuration burden but we have a small program to automatically generate the configuration files for our bramble deployments that uses Kubernetes labels and annotations to build a list of services. It was a small change to our bramble-config-updater to write the two files and we essentially had a complete solution.

Now whenever a team wants to test out a service without affecting the main development environment, a parallel unstable service can be deployed. Our bramble-config-updater decides based on the name if it shadows an existing service or not and then rolls out the updated configuration to our bramble deployments.


The solution we settled on is quite simple and is a welcome confirmation that our stateless and constrained design of Bramble has been a good approach.

From conception to finished solution this only took some exploration with NGINX configuration options and a morning pairing on the bramble-config-updater. Proving that independant composable pieces of code give you the freedom to easily make changes and rearrange in new ways.

Future exploration

Going forward if we find this useful it might be worth investing in expanding the approach. Instead of a single unstable tenant it might be worth looking at having one per feature if the separation proves useful for the teams.

We could also use it for feature flagging customers or deploying debugging versions of services without affecting other clients.

Written by

Adam Johnson

Connect with us