Correlation IDs vs serverless front-end

  • Daniel Pedroso
  • January 23, 2019

What are correlation IDs?

The name itself explains the concept very well - it’s an ID that can be used to… well… correlate things.
Correlation IDs are extremely useful when tracking a request through a distributed application - read micro/nanoservices - especially when trying to understand which services were called and in which order. You simply make sure to include this ID in every single log, and then you’re able to track what actually happened for a particular request.

One issue that frequently arises is: how to inject these correlation IDs into each request if I’m using a serverless front-end (e.g. a react app served directly from an s3 bucket)?

Do I need a service?

Now, I never actually understood why people who are building SPAs insist on adding an edge service (a service to handle all request coming from the front-end before routing them through) just to handle correlation IDs. This is incredibly common.
Your SPA most likely isn’t posting forms back to the API directly (as opposed to handling the request via JS), and if things are correctly separated, your API even lives in a subdomain (e.g. your website is accessible via my-site.com, and your API sits under api.my-site.com)

In short: no, you don’t need an edge service just to inject your correlation ID.

What about the API Gateway?

This is the option number one. You definitely can and even in some cases should use your API gateway to inject this value automatically.
The only problem with this approach is if, for some reason, your service-to-service calls are routed through your API Gateway, too.

Depending on the gateway you’re using, you might get this out of the box. But let’s assume you’re using the AWS API Gateway and Lambda Functions.
In here, you actually get a request ID out of the box. You can simply check for a correlation ID first, and if it’s not set, your request ID becomes the new correlation.
Example:

  const lambda = async (event, context, callback) => {
        // send the x-correlation-id header down to any subsequent calls, and make sure you include it in any logs!
        const correlationID = event.headers['x-correlation-id'] || context.awsRequestId;
  };

What if I can’t use that?

Let’s say you’re using axios to handle your HTTP requests. You need an interceptor like this one:

  import axios from 'axios';
  import { v4 } from 'uuid';

  axios.interceptors.request.use((config) => {
    config.headers['X-CORRELATION-ID'] = v4();
    return config;
  });

Boom, you’ve got yourself correlation IDs being injected in every single request.
Now, I’m sure there are complex scenarios where you might have way more logic here. If that’s the case, then sure, you might be forced to give up on the idea of serving your SPA serverlessly. In that situation, you should ask yourself whether or not that particular requirement is worth the extra costs (in time and money) involved in keeping it.

Do you have a more complex scenario that prevents you from going completely serverless? I would love to hear about it - I’m sincerely interested in figuring out potential solutions to these problems :)