Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀 Feature: Make all requests use a custom User-Agent #24379

Open
2 tasks done
ivangonzalezacuna opened this issue Apr 19, 2024 · 4 comments
Open
2 tasks done

🚀 Feature: Make all requests use a custom User-Agent #24379

ivangonzalezacuna opened this issue Apr 19, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@ivangonzalezacuna
Copy link

🔖 Feature description

Some developers in our company have suggested us to include the User-Agent as part of all the requests that backstage does, whether are internal things or to external services we own.

It would be really nice to support this and allow people to set the header easily. Maybe even set the header to "backstage" per default, which might be super helpful in general for tracing.

🎤 Context

Unfortunately, we haven't found any easy way to do such thing. After some research and trials, I came up with a solution which requires adding a middleware in the backend and in the frontend which simply sets the header to the request. This seems to be working for most scenarios (in the frontend it works if you use the fetchApi, and in the backend it works always).

The only thing that we found out that is not working is related to the swagger-ui-react packagee, which uses its own User-Agent header and is not overridden by own custom one.

✌️ Possible Implementation

The solution I found locally was the following:

In the backend (new backend system), you need to override the defaultConfigure for the rootHttpRouter, and add at the beggining a new middleware which injects the header:

function userAgent(): RequestHandler {
  return (req: Request, _res: Response, next: () => void) => {
    req.headers['user-agent'] = 'backstage';
    next();
  };
}

export function defaultConfigure(context: RootHttpRouterConfigureContext) {
  const { app, routes, middleware, logger } = context;

  app.use(userAgent());
  // the rest of middlewares, routes, etc.)

For the frontend, the solution was kind of similar. In this case, I needed to override the fetchApi definition and add it to our ApiFactory list inside the apis.ts file:

class UserAgentInjector implements FetchMiddleware {
  apply(next: typeof fetch): typeof fetch {
    return async (input, init) => {
      const request = new Request(input as any, init);
      request.headers.set('User-Agent', 'backstage');
      return next(request, init);
    };
  }
}

export const apis: AnyApiFactory[] = [
  // FIXME: Overrides the default fetchApi implementation from https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/apis.ts
  // Make sure it's always up-to-date
  createApiFactory({
    api: fetchApiRef,
    deps: {
      configApi: configApiRef,
      identityApi: identityApiRef,
      discoveryApi: discoveryApiRef,
    },
    factory: ({ configApi, identityApi, discoveryApi }) => {
      return createFetchApi({
        middleware: [
          FetchMiddlewares.resolvePluginProtocol({
            discoveryApi,
          }),
          FetchMiddlewares.injectIdentityAuth({
            identityApi,
            config: configApi,
          }),
          new UserAgentInjector(),
        ],
      });
    },
  }),

  // ...other APIs
];

👀 Have you spent some time to check if this feature request has been raised before?

  • I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

Are you willing to submit PR?

No, but I'm happy to collaborate on a PR with someone else

@ivangonzalezacuna ivangonzalezacuna added the enhancement New feature or request label Apr 19, 2024
@freben
Copy link
Member

freben commented Apr 22, 2024

Am I misremembering or do some browsers still refuse to change that header in outgoing requests?

Hm are you suggesting that maybe this should be something that's supported out of the box instead of adding it yourself? Haven't heard the request for that before, but happy to leave this up fielding for feedback

@ivangonzalezacuna
Copy link
Author

Am I misremembering or do some browsers still refuse to change that header in outgoing requests?

I wasn't aware of such thing, but could be? So far it seems Firefox works fine with the setup I posted above. Not sure about other browsers

Hm are you suggesting that maybe this should be something that's supported out of the box instead of adding it yourself? Haven't heard the request for that before, but happy to leave this up fielding for feedback

Yes, if that's something that more people might be interesting about, it might be a nice idea to have it integrated without needing developers to use a solution like the one we found instead. At least in our case the User-Agent helps us internally in certain scenarios, that's why some people asked us about making backstage use something more specific instead of the default one.

@Rugvip
Copy link
Member

Rugvip commented Apr 23, 2024

More generally on the issue: we have the FetchApi in the frontend for exactly this kind of customization to be possible. It could be that we want to provide some utility to make it a bit easier, but that's the facility that we want to be working with. For backend it's a bit trickier to add a FetchApi but it's still something that we intend to do at some point, or at least attempt. Right now it's not the highest prio though.

@ivangonzalezacuna
Copy link
Author

That sounds like a good plan to me. Having some kind of utility which simplifies setting custom headers (not only the user-agent, maybe others as well) sounds like a big improvement already! ✨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants