Documentation
¶
Overview ¶
Package bind contains model binding features to be used along *lit.Request.
Index ¶
- Variables
- func Body[T any](r *lit.Request) (T, error)
- func Header[T any](r *lit.Request) (T, error)
- func HeaderField[T primitiveType | time.Time](r *lit.Request, header string) (T, error)
- func Query[T any](r *lit.Request) (T, error)
- func Request[T any](r *lit.Request) (T, error)
- func URIParameter[T primitiveType | time.Time](r *lit.Request, parameter string) (T, error)
- func URIParameters[T any](r *lit.Request) (T, error)
- type Error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedContentType = errors.New("unsupported Content-Type")
Functions ¶
func Body ¶
Body binds the request's body into the fields of a struct of type T.
It checks the Content-Type header to select an appropriated parsing method:
- "application/json" for JSON parsing
- "application/xml" or "text/xml" for XML parsing
- "application/x-yaml" for YAML parsing
- "application/x-www-form-urlencoded" for form parsing
Tags from encoding packages, such as "json", "xml" and "yaml" tags, can be used appropriately. For form parsing, use the tag "form".
If the Content-Type header is not set, Body defaults to JSON parsing. If it is not supported, it returns ErrUnsupportedContentType.
If *T implements validate.Validatable (with a pointer receiver), Body calls validate.Fields on the result and can return validate.Error.
If T is not a struct type, Body panics.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
req := httptest.NewRequest(http.MethodPost, "/books", strings.NewReader(`
{"name": "Percy Jackson", "publishYear": 2009}
`))
r := lit.NewRequest(req)
type RequestBody struct {
Name string `json:"name"`
PublishYear int `json:"publishYear"`
}
body, err := bind.Body[RequestBody](r)
if err == nil {
fmt.Println(body.Name)
fmt.Println(body.PublishYear)
}
}
Output: Percy Jackson 2009
func Header ¶
Header binds the request's header into the fields of a struct of type T. Targeted fields should be exported and annotated with the tag "header" (case-insensitive). Otherwise, they are ignored.
If any field couldn't be bound, Header returns Error.
If *T implements validate.Validatable (with a pointer receiver), Header calls validate.Fields on the result and can return validate.Error.
If T is not a struct type, Header panics.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
req := httptest.NewRequest(http.MethodGet, "/books", nil)
req.Header.Add("Content-Length", "150")
req.Header.Add("Authorization", "Bearer uPSsoa65gqkFv2Z6sZ3rZCZwnCjzaXe8TNdk0bJCFFJGrH6wmnzyK4evHBtTuvVH")
r := lit.NewRequest(req)
type Header struct {
ContentLength uint `header:"Content-Length"`
Authorization string `header:"Authorization"`
}
h, err := bind.Header[Header](r)
if err == nil {
fmt.Println(h.ContentLength)
fmt.Println(h.Authorization)
}
}
Output: 150 Bearer uPSsoa65gqkFv2Z6sZ3rZCZwnCjzaXe8TNdk0bJCFFJGrH6wmnzyK4evHBtTuvVH
func HeaderField ¶
HeaderField binds a field from the request's header into a value of type T. T can be either a primitive type or a time.Time.
HeaderField consider header as case-insensitive.
If the value can't be bound into T, HeaderField returns Error.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
req := httptest.NewRequest(http.MethodGet, "/books", nil)
req.Header.Add("Content-Length", "150")
req.Header.Add("Authorization", "Bearer uPSsoa65gqkFv2Z6sZ3rZCZwnCjzaXe8TNdk0bJCFFJGrH6wmnzyK4evHBtTuvVH")
r := lit.NewRequest(req)
contentLength, err := bind.HeaderField[int](r, "Content-Length")
if err == nil {
fmt.Println(contentLength)
}
authorization, err := bind.HeaderField[string](r, "authorization") // case-insensitive
if err == nil {
fmt.Println(authorization)
}
}
Output: 150 Bearer uPSsoa65gqkFv2Z6sZ3rZCZwnCjzaXe8TNdk0bJCFFJGrH6wmnzyK4evHBtTuvVH
func Query ¶
Query binds the request's query parameters into the fields of a struct of type T. Targeted fields should be exported and annotated with the tag "query". Otherwise, they are ignored.
If a field can't be bound, Query returns Error.
If *T implements validate.Validatable (with a pointer receiver), Query calls validate.Fields on the result and can return validate.Error.
If T is not a struct type, Query panics.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
req := httptest.NewRequest(http.MethodGet, "/books", nil)
req.URL.RawQuery = "publish_year=2009&name=Percy%20Jackson"
r := lit.NewRequest(req)
type BookQuery struct {
PublishYear uint `query:"publish_year"`
Name string `query:"name"`
}
query, err := bind.Query[BookQuery](r)
if err == nil {
fmt.Println(query.PublishYear, query.Name)
}
}
Output: 2009 Percy Jackson
func Request ¶
Request binds the request's body, query, header and URI parameters into the fields of a struct of type T. Targeted fields should be exported and annotated with corresponding binding tags. Otherwise, they are ignored.
It's an optimized combination of the binding functions Body, Query, Header and URIParameters, suitable when you need to read from multiple inputs of the request.
If a field can't be bound, Request returns Error.
If *T implements validate.Validatable (with a pointer receiver), Request calls validate.Fields on the result and can return validate.Error.
If T is not a struct type, Request panics.
func URIParameter ¶
URIParameter binds a request's URI parameter into a value of type T. T can be either a primitive type or a time.Time.
If the value can't be bound into T, URIParameter returns Error.
If parameter is not registered as one of the request's expected parameters, URIParameter panics.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
r := lit.NewRequest(
httptest.NewRequest(http.MethodGet, "/users/123/books/book_1", nil),
).WithURIParameters(
map[string]string{"user_id": "123", "book_id": "book_1"},
)
userID, err := bind.URIParameter[int](r, "user_id")
if err == nil {
fmt.Println(userID)
}
}
Output: 123
func URIParameters ¶
URIParameters binds the request's URI parameters into the fields of a struct of type T. Targeted fields should be exported and annotated with the tag "uri". Otherwise, they are ignored.
If a field can't be bound, URIParameters returns Error.
If *T implements validate.Validatable (with a pointer receiver), URIParameters calls validate.Fields on the result and can return validate.Error.
If T is not a struct type, URIParameters panics.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/jvcoutinho/lit"
"github.com/jvcoutinho/lit/bind"
)
func main() {
r := lit.NewRequest(
httptest.NewRequest(http.MethodGet, "/users/123/books/book_1", nil),
).WithURIParameters(
map[string]string{"user_id": "123", "book_id": "book_1"},
)
type RequestURIParameters struct {
UserID int `uri:"user_id"`
BookID string `uri:"book_id"`
}
uri, err := bind.URIParameters[RequestURIParameters](r)
if err == nil {
fmt.Println(uri.UserID, uri.BookID)
}
}
Output: 123 book_1