mirror of
https://github.com/ggicci/httpin.git
synced 2024-11-24 08:32:45 +02:00
🍡 HTTP Input for Go - Decode an HTTP request into a custom struct 📢 the encoding feature will come soon, see branch feat/encoder
https://ggicci.github.io/httpin/
.github/workflows | ||
internal | ||
patch | ||
.gitignore | ||
body_test.go | ||
body.go | ||
chain.go | ||
debug.go | ||
decoders.go | ||
directives_test.go | ||
directives.go | ||
errors.go | ||
form.go | ||
go.mod | ||
go.sum | ||
httpin_test.go | ||
httpin.go | ||
LICENSE | ||
Makefile | ||
README.md | ||
required.go | ||
resolver_test.go | ||
resolver.go |
httpin
HTTP Input for Go - Decode an HTTP request into a custom struct
Define your input struct and then fetch your data!
Quick View
BEFORE (use net/http) | AFTER (use httpin) |
---|---|
|
|
Features
- Builtin directive
form
to decode a field from HTTP query, i.e.http.Request.Form
- Builtin directive
header
to decode a field from HTTP headers, e.g.http.Request.Header
- Builtin decoders used by
form
andheader
directives for basic types, e.g.bool
,int
,int64
,float32
,time.Time
, ... full list - Decode a field by inspecting a set of keys from the same source
- Decode a field from multiple sources, e.g. both query and headers
- Register or replace decoders for both builtin basic types and custom types
- Define input struct with embedded struct fields
- Builtin directive
required
to tag a field as required - Builtin encoders for basic types
- Register or replace encoders for both builtin basic types and custom types
- Register custom directive executors to extend the field resolving abilities, see directive required as an example and think about implementing your own directives like
trim
,to_lowercase
,base58_to_int
, etc.
Sample User Defined Input Structs
type Authorization struct {
// Decode from multiple sources, the former with higher priority
Token string `in:"form=access_token,header=x-api-token"`
}
type Pagination struct {
Page int `in:"form=page"`
// Decode from multiple keys in the same source, the former with higher priority
PerPage int `in:"form=per_page,page_size"`
}
type ListUsersInput struct {
Gender string `in:"form=gender"`
AgeRange []int `in:"form=age_range"`
IsMember bool `in:"form=is_member"`
Pagination // Embedded field works
Authorization // Embedded field works
}
Advanced - Use Middleware
First, set up the middleware for your handlers. We recommend using alice to chain your HTTP middleware functions.
func init() {
mux.Handle("/users", alice.New(
httpin.NewInput(ListUsersInput{}),
).ThenFunc(ListUsers)).Methods("GET")
}
Second, fetch your input with only one line of code.
func ListUsers(rw http.ResponseWriter, r *http.Request) {
input := r.Context().Value(httpin.Input).(*UserQuery)
// do sth.
}