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