userver: gRPC middlewares configuration
Loading...
Searching...
No Matches
gRPC middlewares configuration

If your middleware doesn't have static config options, just use:

  1. ugrpc::server::SimpleMiddlewareFactoryComponent
  2. ugrpc::client::SimpleMiddlewareFactoryComponent

Yaml config for a middleware

To use static config options you need inherit from:

  1. ugrpc::server::MiddlewareFactoryComponentBase
  2. ugrpc::client::MiddlewareFactoryComponentBase
struct MiddlewareConfig final {
std::vector<std::string> headers{};
};
class MetaFilterComponent final : public ugrpc::server::MiddlewareFactoryComponentBase {
public:
static constexpr std::string_view kName = "grpc-server-meta-filter";
MetaFilterComponent(const components::ComponentConfig& config, const components::ComponentContext& context);
static yaml_config::Schema GetStaticConfigSchema();
// Needed to pass static config options to the middleware.
yaml_config::Schema GetMiddlewareConfigSchema() const override;
std::shared_ptr<const MiddlewareBase> CreateMiddleware(
const ugrpc::server::ServiceInfo&,
const yaml_config::YamlConfig& middleware_config
) const override;
};
MiddlewareConfig Parse(const yaml_config::YamlConfig& value, formats::parse::To<MiddlewareConfig>) {
MiddlewareConfig config;
config.headers = value["headers"].As<std::vector<std::string>>();
return config;
}
MetaFilterComponent::MetaFilterComponent(
)
config,
context,
middlewares::MiddlewareDependencyBuilder()
.InGroup<middlewares::groups::User>()
.After<ugrpc::server::middlewares::headers_propagator::Component>()
) {}
std::shared_ptr<const ugrpc::server::MiddlewareBase> MetaFilterComponent::CreateMiddleware(
const yaml_config::YamlConfig& middleware_config
) const {
return std::make_shared<MetaFilter>(middleware_config.As<MiddlewareConfig>());
}
yaml_config::Schema MetaFilterComponent::GetMiddlewareConfigSchema() const { return GetStaticConfigSchema(); }
yaml_config::Schema MetaFilterComponent::GetStaticConfigSchema() {
type: object
description: gRPC service logger component
additionalProperties: false
properties:
headers:
type: array
description: headers names to filter
items:
type: string
description: header name
)");
}

Our middleware will be in the middlewares::groups::User and will be called after headers_propagator middleware. For more information about middlewares order:

See also
gRPC middlewares order.

Then register these components in components::ComponentList. See sample::grpc::auth::server::MetaFilterComponent

int main(int argc, char* argv[]) {
const auto component_list = components::MinimalServerComponentList()
.Append<components::TestsuiteSupport>()
.Append<samples::grpc::auth::GreeterClient>()
.Append<samples::grpc::auth::GreeterServiceComponent>()
.Append<samples::grpc::auth::GreeterHttpHandler>()
.Append<samples::grpc::auth::server::AuthComponent>()
.Append<samples::grpc::auth::server::MetaFilterComponent>()
.Append<samples::grpc::auth::client::AuthComponent>()
.Append<samples::grpc::auth::client::ChaosComponent>();
return utils::DaemonMain(argc, argv, component_list);
}

The static yaml config of middleware. You must add middleware to the config grpc-server-middlewares-pipeline, otherwise the middleware will be disabled everywhere.

grpc-server-meta-filter:
headers:
- global-header
grpc-server-middlewares-pipeline:
middlewares:
grpc-server-meta-filter: # register the middleware in the pipeline
enabled: true

See full srcs:

Config override

Config options are overrided in your components that are inherited from:

  1. ugrpc::server::MiddlewareFactoryComponentBase for the server side.
  2. ugrpc::client::MiddlewareFactoryComponentBase for the client side.

You can override a middleware config like overriding an enabled option.

Example.

grpc-server-meta-filter:
headers:
- global-header
grpc-server-middlewares-pipeline:
middlewares:
grpc-server-meta-filter: # register the middleware in the pipeline
enabled: true
some-service:
middlewares:
grpc-server-meta-filter:
# The middleware of this service will get this header instead of 'global-header'
headers:
- specific-header
Note
Imagine there are more options but you override only headers. Values of other options will be taken from a global config (from grpc-server-middlewares-pipeline)