Interceptores en Controladores gRPC
Sword permite aplicar interceptores a controladores gRPC para validar o transformar la metadata de entrada de las llamadas remotas.
Interceptores tradicionales
En gRPC, OnRequest permite interceptar la solicitud antes de que llegue al método del servicio.
rust
use sword::grpc::*;
use sword::prelude::*;
#[derive(Interceptor)]
struct AuthInterceptor;
impl OnRequest for AuthInterceptor {
async fn on_request(&self, req: Request<()>) -> GrpcInterceptorResult {
if req.metadata().get("authorization").is_none() {
return Err(Status::unauthenticated("missing authorization metadata"));
}
Ok(req)
}
}rust
use sword::prelude::*;
#[controller(kind = Controller::Grpc, service = proto::user_service_server::UserServiceServer)]
#[interceptor(AuthInterceptor)]
struct UsersController;Avance en la cadena de interceptores
A diferencia de los interceptores web, en esta variante no existe next(): el interceptor valida/transforma metadata de entrada y retorna Ok(req) o un Status de error.
Interceptores con configuración
En gRPC puedes usar OnRequestWithConfig<T> para inyectar parámetros de configuración en la validación/intercepción.
rust
use sword::grpc::*;
use sword::prelude::*;
#[derive(Interceptor)]
struct ApiKeyInterceptor;
impl OnRequestWithConfig<&'static str> for ApiKeyInterceptor {
async fn on_request(
&self,
expected_key: &'static str,
req: Request<()>,
) -> GrpcInterceptorResult {
let Some(value) = req.metadata().get("x-api-key") else {
return Err(Status::unauthenticated("missing x-api-key"));
};
let Ok(value) = value.to_str() else {
return Err(Status::unauthenticated("invalid x-api-key"));
};
if value != expected_key {
return Err(Status::permission_denied("invalid x-api-key"));
}
Ok(req)
}
}rust
use sword::prelude::*;
#[controller(kind = Controller::Grpc, service = proto::user_service_server::UserServiceServer)]
#[interceptor(ApiKeyInterceptor, config = "dev-key")]
struct UsersController;
