es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Encadenamiento Condicional de controladores http en Golang

Quiero agregar un manejador http condicionalmente, basado en cierta condición.

func ConditionalCheck(arg string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            ctx := r.Context()
            check, ok := ctx.Value("specific").(bool)
            if check {
                SpecificCheck(arg)
            } else {
                next.ServeHTTP(w, r)
            }
        })
    }
}

func SpecificCheck(arg string) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // algo
            next.ServeHTTP(w, r)
        })
    }
}

chain := alice.New(ConditionalCheck, .........)

Cuando pruebo, la función HandlerFunc de SpecificCheck no se está invocando. ¿Cómo puedo encadenarlo basado en una condición?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Basándonos en el fragmento de código proporcionado, parece que la encadenación debería hacerse utilizando la función alice.New(), donde se pueden pasar múltiples funciones HandlerFunc para crear una cadena de manejadores que se ejecutarán uno tras otro.

    Para agregar condicionalmente un manejador SpecificCheck basado en cierta condición, se puede modificar la función ConditionalCheck para devolver el manejador SpecificCheck o el siguiente manejador (next) basado en la condición.

    Aquí hay un fragmento de código actualizado que demuestra este enfoque:

    func ConditionalCheck(arg string) func(http.Handler) http.Handler {
        return func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                ctx := r.Context()
                check, ok := ctx.Value("specific").(bool)
                if ok && check {
                    SpecificHandler := SpecificCheck(arg)(next)
                    SpecificHandler.ServeHTTP(w, r)
                } else {
                    next.ServeHTTP(w, r)
                }
            })
        }
    }
    
    func SpecificCheck(arg string) func(http.Handler) http.Handler {
        return func(next http.Handler) http.Handler {
            return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                // hacer algo específico
                next.ServeHTTP(w, r)
            })
        }
    }
    
    // crear una cadena de manejadores usando alice.New()
    chain := alice.New(
        ConditionalCheck("some_arg"),
        someOtherHandler,
        anotherHandler,
    )
    

    En este código actualizado, la función ConditionalCheck verifica si se cumple la condición y, si es así, invoca el manejador SpecificCheck pasando el manejador next como argumento. Esto devuelve un nuevo http.Handler que se utiliza para llamar al método ServeHTTP para atender la solicitud.

    Si la condición no se cumple, se invoca directamente el manejador next.

    De esta manera, el manejador SpecificCheck se agrega a la cadena condicionalmente en función del valor de la clave specific en el contexto.

Comments are closed.