Local Development and Subject Mapping
2026-09-05
The point of this post is not to demonstrate converting from HTTP to NATS, although it will showcase a specific benefit where we use subject mapping to compare traditional development with HTTP services and a different way of thinking if you are using NATS services.
I think we all have encountered a time where we needed to make a change in an environment. Let’s say for instance there’s a bug in a service and that service could rely on other services.
In this scenario we would normally:
- Make local changes to code
- Write unit tests to verify
- Run other services locally for integration testing
- Push to dev to test with dev traffic
Our example scenario looks something like this:
There are a few issues with this approach. One being it takes extra resources, both in time and machine resources. If you are testing locally, you need to get a whole environment set up for the integration testing which could mean you need more resources on your local environment. It also means you need to either mock data locally, copy data from dev to your local environment, or connect your local environment to outside resources anyway.
Using a platform like Kubernetes, you have a few options like:
-
port forward each service individually
- Simple but you possible need to adjust vars for all service connections
-
use
kforwardkforwardorkubevpnkubevpn- Need direct access to the cluster
-
use a service mesh that you can run on your machine
- Introduces a lot of complexity
Let’s take a look at a different approach if we back our services with NATS. Like I mentioned earlier, the point here is not to compare NATS to HTTP, but to show how we can think differently about our environments using NATS.
Using our example scenario we could:
- Make local changes to code
- Point NATS traffic for that service directly to our machine.
That’s it. All we do is set up subject mapping with NATS. Now this will obviously add some latency, so if your services are sensitive to the extra round trip latency, this may not work, but I think it will work well for most cases. This means we are able to run only Service A locally, because it still has access to Service B through our existing NATS connection.
So with subject mapping our scenario looks something like this:
Using NATS subject mapping with NATS micros, we can easily map the subject for Service A to a subject which our local Service A is subscribed to.
For example if the service in dev is listening on services.serviceA.>services.serviceA.> we can map that to local.serviceA.>local.serviceA.>. We can also get more granular so we only test one endpoint locally. Something like services.serviceA.POST.endpointservices.serviceA.POST.endpoint mapped to local.serviceA.POST.endpointlocal.serviceA.POST.endpoint or even developername.serviceA.POST.endpointdevelopername.serviceA.POST.endpoint. That way, Service A in the dev environment responds to everything except that specific subject, and our local copy of Service A responds on that specific endpoint.
The diagram above shows we are directly connected to the NATS cluster in our environment. If this is not desired, we could leverage a Leaf Node to proxy our traffic to our internal cluster and either host the leaf node in our infrastructure or leverage Synadia Cloud to route our traffic through.
There is one important thing to note with this setup. While you can do subject mapping in the server config, it requires a config reload. If you want real time mapping it is best to use decentralized authentication. This would allow you to apply mappings at the account level which happen real time and do not need a config reload.