-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrequest.go
More file actions
52 lines (45 loc) · 1.47 KB
/
request.go
File metadata and controls
52 lines (45 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package httpsuite
import (
"errors"
"net/http"
)
// ParseRequest parses the incoming HTTP request into a specified struct type,
// handling JSON decoding, request body limits, path parameter binding, and
// optional validation. Invalid inputs return regular errors instead of panicking.
func ParseRequest[T any](w http.ResponseWriter, r *http.Request, paramExtractor ParamExtractor, opts *ParseOptions, pathParams ...string) (T, error) {
var empty T
if r == nil {
return empty, errNilHTTPRequest
}
if r.Body != nil {
defer func() { _ = r.Body.Close() }()
}
options := normalizeParseOptions(opts)
request, err := DecodeRequestBody[T](r, options.MaxBodyBytes)
if err != nil {
var decodeErr *BodyDecodeError
if !errors.As(err, &decodeErr) {
return empty, err
}
problem, status := problemFromDecodeError(err, options.Problems)
SendResponse[any](w, status, nil, problem, nil)
return empty, err
}
request, err = BindPathParams(request, r, paramExtractor, pathParams...)
if err != nil {
var pathErr *PathParamError
if !errors.As(err, &pathErr) {
return empty, err
}
problem, status := problemFromPathParamError(err, options.Problems)
SendResponse[any](w, status, nil, problem, nil)
return empty, err
}
if !options.SkipValidation {
if problem := ValidateRequest(request, options.Validator); problem != nil {
SendResponse[any](w, validationProblemStatus(problem), nil, problem, nil)
return empty, errValidationFailed
}
}
return request, nil
}