Как создать общее промежуточное ПО для проверки запросов - PullRequest
0 голосов
/ 16 марта 2019

Здесь я хочу создать очень общее промежуточное ПО под названием Expects, которое фактически проверяет текущий запрос в соответствии с предоставленными параметрами.Это повысит Bad Request, если требуемые параметры отсутствуют или пусты.В Python (Flask) это было бы очень просто, например:

@app.route('/endpoint', methods=['POST'])
@expects(['param1', 'param2'])
def endpoint_handler():
    return 'Hello World'

Определение expects будет выглядеть так (очень минимальный пример):

def expects(fields):
    def decorator(view_function):

        @wraps(view_function)
        def wrapper(*args, **kwargs):
            # get current request data
            data = request.get_json(silent=True) or {}          

            for f in fields:
                if f not in data.keys():
                    raise Exception("Bad Request")

            return view_function(*args, **kwargs)

        return wrapper
    return decorator

Я простонемного запутался о том, как бы я достиг этого в Go.До сих пор я пытался:

type RequestParam interface {
    Validate() (bool, error)
}

type EndpointParamsRequired struct {
    SomeParam string `json:"some_param"`
}

func (p *EndpointParamsRequired) Validate() {
    // My validation logic goes here
    if len(p.SomeParam) == 0 {
        return false, "Missing field"
    }
}

func Expects(p RequestParam, h http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Check if present in JSON request

        // Unmarshall JSON
        ...

        if _, err := p.Validate(); err != nil {
            w.WriteHeader(http.StatusBadRequest)
            fmt.Fprintf(w, "Bad request: %s", err)

            return
        }
    }
}

и из main.go файла:

func main() {
    var (
        endopintParams EndpointParamsRequired
    )

    r.HandleFunc("/endpoint", Expects(&endopintParams, EndpointHandler)).Methods("POST")

}

На самом деле он работает впервые и проверяет запрос, но после одного действительного запроса всеПоследовательные запросы успешны, даже если json не содержит требуемого параметра.Это как-то связано с глобальным endopintParams, который я создаю?

...