DHAPI Consumer ID Registration
What is the purpose of a Consumer ID header?
To correlate traffic across backend services to a frontend application, you need a Consumer ID. When a request is made to a MAP endpoint, it often passes through many services. MAP has distributed tracing and telemetry in place to monitor its backend services. This tracing and telemetry can pinpoint traffic from a specific front-end application if the Consumer ID is included in all requests.
Specific Benefits
Targeted troubleshooting of specific transactions
-
MAP teams can quickly isolate traces and logs associated with a single front-end application when diagnosing errors or latency issues.
How do I register my application?
Contact the DHAPI PM, Jeff Roof, at Jeffrey.Roof@va.gov with the following:
-
What VA organization is this project under? (e.g., VHA/DHAS, OIT, OCTO, etc.)
-
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 (e.g., "Retrieve patient appointments from VistA")
-
The email your application’s Consumer ID should be sent to
How should the Consumer ID be used?
All requests to MAP services should include the following header:
VAMF-CONSUMER-ID: <uuid provided by DHAPI team>
The VAMF Consumer ID supports telemetry and tracing. It is not an authentication credential and is not being used for authorization.
What is the best way to include this header?
Store the UUID in an environment variable and, when possible, configure the application’s HTTP client to add the VAMF-CONSUMER-ID header automatically to every MAP request.
Examples
Javascript’s Fetch API
const VAMF_CONSUMER_ID =
import.meta.env.VITE_VAMF_CONSUMER_ID ||
process.env.REACT_APP_VAMF_CONSUMER_ID;
const apiFetch = (url, options = {}) => {
return fetch(url, {
...options,
headers: {
...options.headers,
'VAMF-CONSUMER-ID': VAMF_CONSUMER_ID,
},
});
};
This example preserves any headers supplied by the calling code.
Axios instance
import axios from 'axios';
const VAMF_CONSUMER_ID =
import.meta.env.VITE_VAMF_CONSUMER_ID ||
process.env.REACT_APP_VAMF_CONSUMER_ID;
const api = axios.create({
baseURL: import.meta.env.VITE_MAP_API_URL,
headers: {
'VAMF-CONSUMER-ID': VAMF_CONSUMER_ID,
},
});
export default api;
Axios request interceptor
import axios from 'axios';
const VAMF_CONSUMER_ID =
import.meta.env.VITE_VAMF_CONSUMER_ID ||
process.env.REACT_APP_VAMF_CONSUMER_ID;
const api = axios.create({
baseURL: import.meta.env.VITE_MAP_API_URL,
});
api.interceptors.request.use(
(config) => {
config.headers['VAMF-CONSUMER-ID'] = VAMF_CONSUMER_ID;
return config;
},
(error) => Promise.reject(error)
);
export default api;
Angular’s HttpInterceptor API
import { Injectable } from '@angular/core';
import {
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
@Injectable()
export class VamfConsumerIdInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<unknown>,
next: HttpHandler
): Observable<HttpEvent<unknown>> {
const requestWithConsumerId = req.clone({
setHeaders: {
'VAMF-CONSUMER-ID': environment.vamfConsumerId,
},
});
return next.handle(requestWithConsumerId);
}
}
The corresponding Angular environment configuration would include:
export const environment = {
vamfConsumerId: '<UUID provided by the DHAPI team>',
};