formam alternatives and similar packages
Based on the "Forms" category.
Alternatively, view formam alternatives based on common mentions on social networks and blogs.
-
gorilla/csrf
DISCONTINUED. gorilla/csrf provides Cross Site Request Forgery (CSRF) prevention middleware for Go web applications & services 🔒 -
form
:steam_locomotive: Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support. -
httpin
🍡 HTTP Input for Go - HTTP Request from/to Go Struct (Bi-directional Data Binding between Go Struct and http.Request) -
queryparam
Go package to easily convert a URL's query parameters/values into usable struct values of the correct types. -
checker
Checker is a Go library for validating user input through checker rules provided in struct tags. -
gbind
Bind data to any Go value. Can use built-in and custom expression binding capabilities; supports data validation logic for Go values. // 将数据绑定到任何 Go 值。可使用内置和自定义表达式绑定能力;支持对Go值的数据校验逻辑.
CodeRabbit: AI Code Reviews for Developers
Do you think we are missing an alternative of formam or a related project?
Popular Comparisons
README
formam
A Go package to decode HTTP form and query parameters. The only requirement is Go 1.12 or later.
Install
go get github.com/monoculum/formam/v3
Features
- Infinite nesting for
maps
,structs
andslices
. - Support
UnmarshalText()
interface in values and keys of maps. - Supported
map
keys arestring
,int
and variants,uint
and variants,uintptr
,float32
,float64
,bool
,struct
,custom types
to one of the above types registered by function orUnmarshalText
method, apointer
to one of the above types - A field with
interface{}
that has amap
,struct
orslice
as value is accessible. - Decode
time.Time
with format2006-01-02
by itsUnmarshalText()
method. - Decode
url.URL
. - Append to
slice
andarray
types without explicitly indicating an index. - Register a function for a custom type.
Performance
You can see the performance in formam-benchmark compared with ajg/form, gorilla/schema, go-playground/form and built-in/json.
Basic usage example
In form HTML
- Use
.
to access a struct field (e.g.struct.field1
). - Use
[<index>]
to access tje specific slice/array index (e.g.struct.array[0]
). It's not necessary to add an index to append data. - Use
[<key>]
to access map keys (e.g..struct.map[es-ES]
).
<form method="POST">
<input type="text" name="Name" value="Sony" />
<input type="text" name="Location.Country" value="Japan" />
<input type="text" name="Location.City" value="Tokyo" />
<input type="text" name="Products[0].Name" value="Playstation 4" />
<input type="text" name="Products[0].Type" value="Video games" />
<input type="text" name="Products[1].Name" value="TV Bravia 32" />
<input type="text" name="Products[1].Type" value="TVs" />
<input type="text" name="Founders[0]" value="Masaru Ibuka" />
<input type="text" name="Founders[0]" value="Akio Morita" />
<input type="text" name="Employees" value="90000" />
<input type="text" name="public" value="true" />
<input type="url" name="website" value="http://www.sony.net" />
<input type="date" name="foundation" value="1946-05-07" />
<input type="text" name="Interface.ID" value="12" />
<input type="text" name="Interface.Name" value="Go Programming Language" />
<input type="submit" />
</form>
In Go
You can use the formam
struct tag to ensure the form values are unmarshalled in the currect struct fields.
type InterfaceStruct struct {
ID int
Name string
}
type Company struct {
Public bool `formam:"public"`
Website url.URL `formam:"website"`
Foundation time.Time `formam:"foundation"`
Name string
Location struct {
Country string
City string
}
Products []struct {
Name string
Type string
}
Founders []string
Employees int64
Interface interface{}
}
func MyHandler(w http.ResponseWriter, r *http.Request) error {
r.ParseForm()
m := Company{
// it's is possible to access to the fields although it's an interface field!
Interface: &InterfaceStruct{},
}
dec := formam.NewDecoder(&formam.DecoderOptions{TagName: "formam"})
return dec.Decode(r.Form, &m)
}
Types
Supported types in the destination struct are:
string
bool
int
,int8
,int16
,int32
,int64
uint
,uint8
,uint16
,uint32
,uint64
float32
,float64
slice
,array
struct
andstruct anonymous
map
interface{}
time.Time
url.URL
custom types
to one of the above types- a
pointer
to one of the above types
Custom Marshaling
You can umarshal data and map keys by implementing the encoding.TextUnmarshaler
interface.
If the forms sends multiple values then only the first value is passed to UnmarshalText()
, but if the name ends with []
then it's called for all values.
Custom Type
You can register a function for a custom type using the RegisterCustomType()
method. This will work for any number of given fields or all fields with the given type.
Registered type have preference over the UnmarshalText method unless the PrefUnmarshalText
option is used.
All fields
decoder.RegisterCustomType(func(vals []string) (interface{}, error) {
return time.Parse("2006-01-02", vals[0])
}, []interface{}{time.Time{}}, nil)
Specific fields
package main
type Times struct {
Timestamp time.Time
Time time.Time
TimeDefault time.Time
}
func main() {
var t Timestamp
dec := NewDecoder(nil)
// for Timestamp field
dec.RegisterCustomType(func(vals []string) (interface{}, error) {
return time.Parse("2006-01-02T15:04:05Z07:00", vals[0])
}, []interface{}{time.Time{}}, []interface{}{&t.Timestamp{}})
// for Time field
dec.RegisterCustomType(func(vals []string) (interface{}, error) {
return time.Parse("Mon, 02 Jan 2006 15:04:05 MST", vals[0])
}, []interface{}{time.Time{}}, []interface{}{&t.Time{}})
// for field that not be Time or Timestamp, e.g. in this example, TimeDefault.
dec.RegisterCustomType(func(vals []string) (interface{}, error) {
return time.Parse("2006-01-02", vals[0])
}, []interface{}{time.Time{}}, nil)
dec.Decode(url.Values{}, &t)
}
Notes
Version 2 is compatible with old syntax to access to maps (map.key
), but brackets are the preferred way to access a map (map[key])
.