Удивительно, но KrakenD (API Gateway) не предоставляет из коробки генерации уникального идентификатора запроса.. вернее представляет, но не так как это хотелось бы.
Документация говорит, что можно воспользоваться модификатором запроса, который действительно добавит этот заголовок, но лишь в сам запрос, не в ответ, так еще и без возможности изменить само наименование этого заголовка..
Еще более удивительно, что в общем доступен нет решения, по крайней мере которое я смог нагуглить за пол часа.
Решил написать свой плагин, за одно разобраться как это дело работает.
В самом KrakenD есть несколько типов плагинов, которые подключаются в разные моменты и имеют разный контекст исполнения, но это все детально описано в документации.
Код предельно прост:
...
func (r registerer) registerHandlers(
c context.Context,
extra map[string]interface{},
h http.Handler,
) (http.Handler, error) {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
requestID := uuid.New().String()
r := req.WithContext(c)
r.Header.Set(headerName, requestID)
w.Header().Set(headerName, requestID)
h.ServeHTTP(w, r)
}), nil
}
Генерируем UUID и пропихиваем его как в тело запроса, так и в ответ.
Т.к. конкретно в моем случае микро-сервисы передают этот заголовок глубже для меня сохраняется возможность трассировки запроса включая взаимодействие сервисов друг с другом.
Для регистрации плагин необходимо скомпилировать с той же версией go с которой был собран KrakenD и прописать его в конфиге:
"plugin": {
"pattern": ".so",
"folder": "/etc/krakend/plugins/" // путь до собранных .so плагинов, которые сканирует и подгружает KrakenD
},
"extra_config": {
"plugin/http-server": { // тип плагина
"name": [
"RequestUUIDMarker" // название плагина
]
}
}
Для удобства сборки в Docker окружении имеется официальный образ конкретно для компиляции плагинов, с которым итоговый Dockerfile выглядит примерно следующим образом:
FROM krakend/builder:2.9.4 as plugins
WORKDIR /build
COPY .docker/container/krakend-public/plugins/ .
RUN cd /build/request-uuid-marker/ && go build -buildmode=plugin -o ../output/request-uuid-marker.so ./request-uuid-marker.go
FROM krakend:2.9.4
ENV FC_ENABLE=1
COPY --from=plugins /build/output/ /etc/krakend/plugins/
P.S.: если этот заголовок планируется использовать в браузере, ему необходимо явно разрешить его использовать путем добавления заголовка: Access-Control-Expose-Headers: X-REQUEST-ID для Nginx и/или в самом конфиге KrakenD:
"security/cors": {
...
"expose_headers": ["X-Request-Id"]
},
P.S.S: локально используя Docker и процессоры M* (скорее всего любые ARM) лучше указать конкретную платформу для образов platform: "linux/x86_64", в противном случае придется танцевать с бубном при сборке.

