Здесь я хочу создать очень общее промежуточное ПО под названием 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
, который я создаю?