mirror of
https://github.com/Fishwaldo/huma.git
synced 2025-03-15 11:21:42 +00:00
feat: add RawBody support and UnsupportedMediaType response
This commit is contained in:
parent
73c101e7f0
commit
0a73c646f1
5 changed files with 59 additions and 1 deletions
14
README.md
14
README.md
|
@ -374,7 +374,7 @@ The following types are supported out of the box:
|
|||
|
||||
For example, if the parameter is a query param and the type is `[]string` it might look like `?tags=tag1,tag2` in the URI.
|
||||
|
||||
The special struct field `Body` will be treated as the input request body and can refer to another struct or you can embed a struct inline.
|
||||
The special struct field `Body` will be treated as the input request body and can refer to another struct or you can embed a struct inline. `RawBody` can also be used to provide access to the `[]byte` used to validate & load `Body`.
|
||||
|
||||
Here is an example:
|
||||
|
||||
|
@ -472,6 +472,18 @@ op.NoBodyReadTimeout()
|
|||
op.Run(...)
|
||||
```
|
||||
|
||||
If you just need access to the input body bytes and still want to use the built-in JSON Schema validation, then you can instead use the `RawBody` input struct field.
|
||||
|
||||
```go
|
||||
type MyBody struct {
|
||||
// This will generate JSON Schema, validate the input, and parse it.
|
||||
Body MyStruct
|
||||
|
||||
// This will contain the raw bytes used to load the above.
|
||||
RawBody []byte
|
||||
}
|
||||
```
|
||||
|
||||
### Resolvers
|
||||
|
||||
Sometimes the built-in validation isn't sufficient for your use-case, or you want to do something more complex with the incoming request object. This is where resolvers come in.
|
||||
|
|
|
@ -251,6 +251,12 @@ func setFields(ctx *hcontext, req *http.Request, input reflect.Value, t reflect.
|
|||
Value: string(data),
|
||||
})
|
||||
}
|
||||
|
||||
// If requested, also provide access to the raw body bytes.
|
||||
if _, ok := t.FieldByName("RawBody"); ok {
|
||||
input.FieldByName("RawBody").Set(reflect.ValueOf(data))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -327,3 +327,36 @@ func TestStringQueryEmpty(t *testing.T) {
|
|||
assert.Equal(t, o.BooleanParam, true)
|
||||
assert.Equal(t, o.OtherParam, "")
|
||||
}
|
||||
|
||||
func TestRawBody(t *testing.T) {
|
||||
app := newTestRouter()
|
||||
|
||||
app.Resource("/").Get("test", "Test",
|
||||
NewResponse(http.StatusOK, "desc"),
|
||||
).Run(func(ctx Context, input struct {
|
||||
Body struct {
|
||||
Name string `json:"name"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
RawBody []byte
|
||||
}) {
|
||||
ctx.Write(input.RawBody)
|
||||
})
|
||||
|
||||
// Note the weird formatting
|
||||
body := `{ "name" : "Huma","tags": [ "one" ,"two"]}`
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
r, _ := http.NewRequest(http.MethodGet, "/", strings.NewReader(body))
|
||||
app.ServeHTTP(w, r)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
|
||||
assert.Equal(t, body, w.Body.String())
|
||||
|
||||
// Invalid input should still fail validation!
|
||||
w = httptest.NewRecorder()
|
||||
r, _ = http.NewRequest(http.MethodGet, "/", strings.NewReader("{}"))
|
||||
app.ServeHTTP(w, r)
|
||||
|
||||
assert.Equal(t, http.StatusUnprocessableEntity, w.Result().StatusCode)
|
||||
}
|
||||
|
|
|
@ -113,6 +113,11 @@ func RequestEntityTooLarge() huma.Response {
|
|||
return errorResponse(http.StatusRequestEntityTooLarge)
|
||||
}
|
||||
|
||||
// UnsupportedMediaType HTTP 415 response with a structured error body (e.g. JSON).
|
||||
func UnsupportedMediaType() huma.Response {
|
||||
return errorResponse(http.StatusUnsupportedMediaType)
|
||||
}
|
||||
|
||||
// UnprocessableEntity HTTP 422 response with a structured error body (e.g. JSON).
|
||||
func UnprocessableEntity() huma.Response {
|
||||
return errorResponse(http.StatusUnprocessableEntity)
|
||||
|
|
|
@ -33,6 +33,7 @@ var funcs = struct {
|
|||
RequestTimeout,
|
||||
Conflict,
|
||||
PreconditionFailed,
|
||||
UnsupportedMediaType,
|
||||
RequestEntityTooLarge,
|
||||
UnprocessableEntity,
|
||||
PreconditionRequired,
|
||||
|
@ -72,6 +73,7 @@ func TestResponses(t *testing.T) {
|
|||
http.StatusConflict,
|
||||
http.StatusPreconditionFailed,
|
||||
http.StatusRequestEntityTooLarge,
|
||||
http.StatusUnsupportedMediaType,
|
||||
http.StatusUnprocessableEntity,
|
||||
http.StatusPreconditionRequired,
|
||||
http.StatusInternalServerError,
|
||||
|
|
Loading…
Add table
Reference in a new issue