DHAPI App ID Registration

What is the purpose of an App ID header?

To correlate traffic across backend services to a frontend application, an App ID is required. When a request is made to a MAP endpoint, the request often works its way through many services. MAP has distributed tracing and telemetry in place to monitor its backend services. This tracing and telemetry can zero in on traffic from a specific front end application if the App ID is included in all requests.

Specific Benefits

Targeted troubleshooting of specific transactions

MAP teams can quickly isolate traces and logs tied to a single front-end application when diagnosing errors or latency.

End-to-end visibility into microservice workflows

See how a single MAP request propagates across services, where time is spent, and where failures or retries occur.

Application-level telemetry

Measure error rates, latency, and traffic volume by consuming application, not just by endpoint.

How do I register my application?

Contact the DHAPI PM, Jeff Roof at Jeffrey.Roof@va.gov with the following:

  • The contract for your application

  • Business POC (Name, email, phone number)

  • Technical POC (Name, email, phone number)

  • The name of your application

  • A brief description of how your application will be using MAP services

  • The email your application’s App ID should be sent to

How should the App ID be used?

All requests to MAP services should include the following header:

APP-ID: <uuid provided by DHAPI team>

What is the best way to include this header?

The uuid should be injected into your application as an environment variable then globally added to the http client used by the application if possible.

Examples

Javascript’s fetch API
const APP_ID = import.meta.env.VITE_API_URL;
OR
const APP_ID = process.env.REACT_APP_API_URL;

const apiFetch = (url, options) => {
  return fetch(url, {
    ...options,
    headers: {
      'APP-ID': APP_ID
    },
  });
};
The Javascript library Axios
import axios from 'axios';

const APP_ID = import.meta.env.VITE_API_URL
OR
const APP_ID = process.env.REACT_APP_API_URL;

const api = axios.create({
  baseURL: APP_ID,
  headers: {
    'APP-ID': APP_ID,
  },
});

OR

api.interceptors.request.use(
  (config) => {
    config.headers['APP-ID'] = APP_ID;
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);
Angular’s HttpInterceptor API
import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';

@Injectable()
export class AppIdInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const clonedReq = req.clone({
      setHeaders: {
        'APP-ID': environment.appId,
      },
    });
    return next.handle(clonedReq);
  }
}