如何创建通用请求验证中间件

时间:2019-03-16 13:05:09

标签: go go-http

我在这里想要实现的是创建一个名为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有什么关系吗?

0 个答案:

没有答案