--- name: rate_limiter_by_key kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func RateLimiterByKey(rl *RateLimiter, keyFunc func(r *http.Request) string) Middleware" description: "Middleware HTTP configurable que aplica rate limiting con un extractor de clave custom. Permite limitar por API key, user ID, header arbitrario, etc. Si keyFunc devuelve cadena vacia el request pasa sin limit." tags: [rate_limit, http, middleware, custom, key, server, infra] uses_functions: [rate_limiter_check_go_infra, rate_limit_headers_go_infra, http_error_response_go_infra] uses_types: [RateLimiter_go_infra, Middleware_go_infra, HTTPError_go_infra] returns: [Middleware_go_infra] returns_optional: false error_type: "error_go_core" imports: [net/http] params: - name: rl desc: "puntero al RateLimiter compartido entre todos los requests" - name: keyFunc desc: "funcion que extrae la clave del request (API key, user ID, etc.). Cadena vacia salta el limit" output: "Middleware que aplica rate limit segun keyFunc, responde 429 con HTTPError JSON al exceder" tested: true tests: ["aplica limit por la clave devuelta por keyFunc", "key vacia salta el limit", "responde 429 con body JSON al exceder", "headers X-RateLimit-* siempre presentes en respuesta"] test_file_path: "functions/infra/rate_limiter_by_key_test.go" file_path: "functions/infra/rate_limiter_by_key.go" --- ## Ejemplo ```go // Limit por API key rl := RateLimiterNew(100, 200) mw := RateLimiterByKey(rl, func(r *http.Request) string { return r.Header.Get("X-API-Key") }) // Limit por user ID extraido del JWT (suponiendo middleware previo que lo setea) mwUser := RateLimiterByKey(rl, func(r *http.Request) string { return r.Context().Value("user_id").(string) }) ``` ## Notas Funcion impura — el middleware muta el estado del limiter. Reutiliza `RateLimiterCheck`, `RateLimitHeaders` y `HTTPErrorResponse` del registry. Si el keyFunc devuelve "" se interpreta como "sin clave identificable" y se deja pasar el request: util para endpoints publicos donde solo se quiere limitar requests autenticados. La respuesta 429 sigue el formato JSON estandar `{"status":429,"code":"rate_limited","message":"too many requests"}`.