Documentation
¶
Overview ¶
Package webfmwk implements a json API server ready
Hello world example:
package main import ( "github.com/burgesQ/webfmwk/v6" ) // Handler func hello(c webfmwk.Context) error { return c.JSONOk("Hello, world!") } func main() { // Echo instance s := webfmwk.InitServer(webfmwk.WithCtrlC()) // Routes s.GET("/hello", hello) // ctrl+c is handled internaly defer s.WaitAndStop() // start server on :4242 s.Start(":4242") }
Some extra feature are available like : tls, custom handler/logger/context, redoc support and more ... Find other examples at https://github.com/burgesQ/webfmwk/tree/master/example.
Index ¶
- Constants
- Variables
- func GetIPFromRequest(fc *fasthttp.RequestCtx) string
- func HandleError(ctx Context, e error)
- func RegisterValidatorAlias(name, what string) (e error)
- func RegisterValidatorRule(name string, fn func(fl validator.FieldLevel) bool) (e error)
- func RegisterValidatorTrans(name, what string) (e error)
- func Shutdown() error
- func Tern[T any](cond bool, t, f func() T) T
- func UseOption(s *Server, o Option)
- type Address
- type Addresses
- type Context
- type ContextLogger
- type DocHandler
- type Error
- type ErrorHandled
- func NewBadRequest(content interface{}) ErrorHandled
- func NewConflict(content interface{}) ErrorHandled
- func NewErrorHandled(op int, content interface{}) ErrorHandled
- func NewForbidden(content interface{}) ErrorHandled
- func NewInternal(content interface{}) ErrorHandled
- func NewNoContent() ErrorHandled
- func NewNotAcceptable(content interface{}) ErrorHandled
- func NewNotFound(content interface{}) ErrorHandled
- func NewNotImplemented(content interface{}) ErrorHandled
- func NewProcessing(content interface{}) ErrorHandled
- func NewServiceUnavailable(content interface{}) ErrorHandled
- func NewUnauthorized(content interface{}) ErrorHandled
- func NewUnprocessable(content interface{}) ErrorHandled
- type ErrorValidation
- type FastLogger
- type Handler
- type HandlerFunc
- type Header
- type IAddress
- type InputHandling
- type JSONHTTPResponse
- type JSONResponse
- type Option
- func CheckIsUp() Option
- func EnableKeepAlive() Option
- func EnablePprof(path ...string) Option
- func MaxRequestBodySize(size int) Option
- func SetIDLETimeout(val time.Duration) Option
- func SetPrefix(prefix string) Option
- func SetReadTimeout(val time.Duration) Option
- func SetWriteTimeout(val time.Duration) Option
- func WithCORS() Option
- func WithCtrlC() Option
- func WithDocHandlers(handler ...DocHandler) Option
- func WithHTTP2() Option
- func WithHandlers(h ...Handler) Option
- func WithSocketHandler(path string, h http.Handler) Option
- func WithSocketHandlerFunc(path string, hf http.HandlerFunc) Option
- func WithStructuredLogger(slg *slog.Logger) Option
- type Options
- type Response
- type Route
- type Routes
- type RoutesPerPrefix
- type SendResponse
- type Server
- func (s *Server) ANY(path string, handler HandlerFunc)
- func (s *Server) AddRoutes(r ...Route)
- func (s *Server) CustomHandler(handler HandlerFunc) fasthttp.RequestHandler
- func (s *Server) DELETE(path string, handler HandlerFunc)
- func (s *Server) DisableHTTP2() *Server
- func (s *Server) DumpRoutes() map[string][]string
- func (s *Server) EnableCheckIsUp() *Server
- func (s *Server) GET(path string, handler HandlerFunc)
- func (s *Server) GetCancel() context.CancelFunc
- func (s *Server) GetContext() context.Context
- func (s *Server) GetLauncher() WorkerLauncher
- func (s *Server) GetRouter() *router.Router
- func (s *Server) GetStructuredLogger() *slog.Logger
- func (s *Server) IsReady() chan bool
- func (s *Server) PATCH(path string, handler HandlerFunc)
- func (s *Server) POST(path string, handler HandlerFunc)
- func (s *Server) PUT(path string, handler HandlerFunc)
- func (s *Server) RouteApplier(rpps ...RoutesPerPrefix)
- func (s *Server) Run(addrs ...Address)
- func (s *Server) Shutdown() error
- func (s *Server) ShutdownAndWait() error
- func (s *Server) Start(addr string)
- func (s *Server) StartTLS(addr string, cfg tls.IConfig)
- func (s *Server) StartUnixSocket(path string) error
- func (s *Server) WaitForStop()
- type ValidationError
- type Worker
- type WorkerLauncher
Constants ¶
const ( ReadTimeout = 20 WriteTimeout = 20 IdleTimeout = 1 )
const ( // GET http verbe GET = "GET" // POST http verbe POST = "POST" // PATCH http verbe PATCH = "PATCH" // PUT http verbe PUT = "PUT" // DELETE http verbe DELETE = "DELETE" ANY = "ANY" )
const UnprocessablePayloadErrorStr = `{"message":"unprocessable payload content","status":422}`
Variables ¶
var ( // ErrMissingContentType is returned in case of missing content type header. ErrMissingContentType = NewNotAcceptable(NewError("Missing Content-Type header")) // ErrNotJSON is returned when the content type isn't json ErrNotJSON = NewNotAcceptable(NewError("Content-Type is not application/json")) )
var ErrGetTranslator = errors.New("fetching the 'en' translator")
Functions ¶
func GetIPFromRequest ¶
func GetIPFromRequest(fc *fasthttp.RequestCtx) string
GetIPFromRequest try to extract the source IP from the request headers (X-Real-IP and X-Forwareded-For).
func HandleError ¶
HandleError test if the error argument implement the ErrorHandled interface to return a matching response. Otherwise, a 500/internal error is generated from the error arguent.
func RegisterValidatorAlias ¶
RegisterValidatorAlias register some validation alias. See https://go-playground/validator.v10 for more.
func RegisterValidatorRule ¶
func RegisterValidatorRule(name string, fn func(fl validator.FieldLevel) bool) (e error)
RegisterValidatorRule register the validation rule param. See https://go-playground/validator.v10 for more.
func RegisterValidatorTrans ¶
RegisterValidatorTrans register some validation alias. See https://go-playground/validator.v10 for more.
Types ¶
type Address ¶
type Address struct { // TLS implement IAddress, tlsConfig implement the TLSConfig interface. TLS *tls.Config `json:"tls,omitempty" mapstructure:"tls,omitempty"` Addr string `json:"addr"` Name string `json:"name"` }
Address implement the IAddress interface
func (Address) IsUnixPath ¶ added in v6.0.2
IsOk implement the IAddress interface
type Addresses ¶
type Addresses []Address
type Context ¶
type Context interface { SendResponse InputHandling ContextLogger // GetFastContext return a pointer to the internal fasthttp.RequestCtx. GetFastContext() *fasthttp.RequestCtx // GetContext return the request context.Context. GetContext() context.Context // GetVar return the url var parameters. An empty string for missing case. GetVar(key string) (val string) // GetQueries return the queries into a fasthttp.Args object. GetQuery() *fasthttp.Args }
Context interface implement the context used in this project.
type ContextLogger ¶
type ContextLogger interface { // SetStructuredLogger set context' structured logger. SetStructuredLogger(logger *slog.Logger) Context // GetStructuredLogger return context' structured logger. GetStructuredLogger() *slog.Logger }
ContextLogger interface implement the context Logger needs.
type DocHandler ¶
type DocHandler struct { // H hold the doc Handler to expose. H HandlerFunc // Name is used in debug message. Name string // Path hold the URI one which the handler is reachable. // If a prefix is setup, the path will prefixed. Path string }
DocHandler hold the required data to expose a swagger documentation handlers.
Example serving a redoc one:
import ( github.com/burgesQ/webfmwk/v6 github.com/burgesQ/webfmwk/handler/redoc ) s := webfmwk.InitServer( webfmwk.WithDocHandler(redoc.GetHandler( redoc.DocURI("/swagger.json") )) s.Get("/swagger.json", func(c webfmwk.Context) error{ return c.JSONBlob(200, `{"title": "some swagger"`) })
type Error ¶
type Error struct { // Message hold the error message. // // Example: the impossible appened Message string `json:"message" example:"no such resource" validate:"required"` // Status hold the error code status. // // Example: 500 Status int `json:"status" validate:"required"` // contains filtered or unexported fields }
Error struct is used to answer http error.
func NewCustomWrappedError ¶
NewCustomWrappedError generate a Error which wrap the err parameter but return the msg one.
func NewErrorFromError ¶
NewErrorFromError generate a Error which wrap the err parameter.
func (*Error) SetStatusCode ¶
SetStatusCode set the error status code.
type ErrorHandled ¶
type ErrorHandled interface { // Error implelement the Error interface. Error() string // GetOPCode return the http status code response associated to the error. GetOPCode() int // SetStatusCode set the error associated http status code. SetStatusCode(op int) ErrorHandled // GetContent return the error http response content. GetContent() interface{} }
ErrorHandled interface is used to ease the error processing.
func NewBadRequest ¶
func NewBadRequest(content interface{}) ErrorHandled
NewBadRequest produce an handledError with the status code 400.
func NewConflict ¶
func NewConflict(content interface{}) ErrorHandled
NewConflict produce an ErrorHandled with the status code 409.
func NewErrorHandled ¶
func NewErrorHandled(op int, content interface{}) ErrorHandled
NewErrorHandled return a struct implementing ErrorHandled with the provided params.
func NewForbidden ¶
func NewForbidden(content interface{}) ErrorHandled
NewForbidden produce an ErrorHandled with the status code 403.
func NewInternal ¶
func NewInternal(content interface{}) ErrorHandled
NewInternal produce an ErrorHandled with the status code 500.
func NewNoContent ¶
func NewNoContent() ErrorHandled
NewNoContent produce an ErrorHandled struct with the status code 204.
func NewNotAcceptable ¶
func NewNotAcceptable(content interface{}) ErrorHandled
NewNotAcceptable produce an ErrorHandled with the status code 406.
func NewNotFound ¶
func NewNotFound(content interface{}) ErrorHandled
NewNotFound produce an ErrorHandled with the status code 404.
func NewNotImplemented ¶
func NewNotImplemented(content interface{}) ErrorHandled
NewNotImplemented produce an ErrorHandled with the status code 501.
func NewProcessing ¶
func NewProcessing(content interface{}) ErrorHandled
NewProcessing produce an ErrorHandled struct with the status code 102.
func NewServiceUnavailable ¶
func NewServiceUnavailable(content interface{}) ErrorHandled
NewServiceUnavailable produce an ErrorHandled with the status code 503.
func NewUnauthorized ¶
func NewUnauthorized(content interface{}) ErrorHandled
NewUnauthorized produce an ErrorHandled with the status code 401.
func NewUnprocessable ¶
func NewUnprocessable(content interface{}) ErrorHandled
NewUnprocessable produce an ErrorHandled with the status code 422.
type ErrorValidation ¶
ErrorsValidation is a map of translated errors
func TranslateAndUseFieldName ¶
func TranslateAndUseFieldName(errs validator.ValidationErrors) ErrorValidation
Trnaslate the errs array of validation error and use the actual filed name instad of the full struct namepsace one. src: https://blog.depa.do/post/gin-validation-errors-handling#toc_8
type FastLogger ¶ added in v6.0.1
func (*FastLogger) Printf ¶ added in v6.0.1
func (flg *FastLogger) Printf(msg string, keys ...any)
type Handler ¶
type Handler func(HandlerFunc) HandlerFunc
Handler hold the function signature for webfmwk Handler chaning (middlware).
import ( github.com/burgesQ/webfmwk/v6 github.com/burgesQ/webfmwk/handler/logging github.com/burgesQ/webfmwk/handler/security ) s := webfmwk.InitServer( webfmwk.WithHandler( logging.Handler, security.Handler, ))
type HandlerFunc ¶
HandlerFunc hold the signature of a Handler. You may return an error implementing the ErrorHandled interface to reduce the boilerplate. If the returned error doesn't implement the interface, a error 500 is by default returned.
HandlerError(c webfmwk.Context) error { return webfmwk.NewUnauthorizedError("get me some credential !") }
Will produce a http 500 json response.
type IAddress ¶
type IAddress interface { fmt.Stringer // GetAddr return the listing address. GetAddr() string // GetTLS return a pointer to an TLSConfig if present, nil otherwise. GetTLS() tls.IConfig // GetName return the name of the address, for debug purpose. GetName() string // IsOk validate that the Address structure have at least the address field populated. IsOk() bool // IsUnixPath return true if the address is a valid unix socket path. IsUnixPath() bool // SameAs return true if both config are identique. SameAs(in IAddress) bool }
IAddress interface hold an api server listing configuration
type InputHandling ¶
type InputHandling interface { // FetchContent extract the json content from the body into the content interface. FetchContent(content interface{}) ErrorHandled // Validate is used to validate a content of the content params. // See https://go-playground/validator.v10 for more. Validate(content interface{}) ErrorHandled // FetchAndValidateContent fetch the content then validate it. FetchAndValidateContent(content interface{}) ErrorHandled // DecodeQP load the query param in the content object. // Seee https://github.com/gorilla/query for more. DecodeQP(content interface{}) ErrorHandled // DecodeAndValidateQP load the query param in the content object and then validate it. DecodeAndValidateQP(content interface{}) ErrorHandled }
InputHandling interface introduce I/O actions.
type JSONHTTPResponse ¶
type JSONHTTPResponse interface { // JSONOk return the interface with an http.StatusOK (200). JSONOk(content interface{}) error // JSONCreated return the interface with an http.StatusCreated (201). JSONCreated(content interface{}) error // JSONAccepted return the interface with an http.StatusAccepted (202). JSONAccepted(content interface{}) error // JSONNoContent return an empty payload an http.StatusNoContent (204). JSONNoContent() error // JSONBadRequest return the interface with an http.StatusBadRequest (400). JSONBadRequest(content interface{}) error JSONUnauthorized(content interface{}) error // JSONForbiden return the interface with an http.StatusForbidden (403). JSONForbidden(content interface{}) error // JSONNoContent return the interface with an http.StatusNotFound (404). JSONNotFound(content interface{}) error // JSONMethodNotAllowed return the interface with an http.NotAllowed (405). JSONMethodNotAllowed(content interface{}) error // JSONConflict return the interface with an http.StatusConflict (409). JSONConflict(content interface{}) error // JSONUnauthorized return the interface with an http.StatusUnprocessableEntity (422). JSONUnprocessable(content interface{}) error // JSONInternalError return the interface with an http.StatusInternalServerError (500). JSONInternalError(content interface{}) error // JSONNotImplemented return the interface with an http.StatusNotImplemented (501). JSONNotImplemented(content interface{}) error }
type JSONResponse ¶
type JSONResponse interface { JSONHTTPResponse // JSONBlob answer the JSON content with the status code op. JSONBlob(op int, content []byte) error // JSON answer the JSON content with the status code op. JSON(op int, content interface{}) error }
JSONResponse interface is used to answer JSON content to the client.
type Option ¶
type Option func(s *Server)
Option apply specific configuration to the server at init time They are tu be used this way :
s := w.InitServer( webfmwk.WithStructuredLogger(slog.Default()), webfmwk.WithCtrlC(), webfmwk.CheckIsUp(), webfmwk.WithCORS(), webfmwk.SetPrefix("/api"), webfmwk.WithDocHanlders(redoc.GetHandler()), webfmwk.SetIdleTimeout(1 * time.Second), webfmwk.SetReadTimeout(1 * time.Second), webfmwk.SetWriteTimeout(1 * time.Second), webfmwk.WithHanlders( recover.Handler, logging.Handler, security.Handler))
func CheckIsUp ¶
func CheckIsUp() Option
CheckIsUp expose a `/ping` endpoint and try to poll to check the server healt when it's started.
func EnableKeepAlive ¶
func EnableKeepAlive() Option
EnableKeepAlive disable the server keep alive functions.
func MaxRequestBodySize ¶
func SetIDLETimeout ¶
SetIDLETimeout the server IDLE timeout AKA keepalive timeout.
func SetReadTimeout ¶
SetReadTimeout is a timing constraint on the client http request imposed by the server from the moment of initial connection up to the time the entire request body has been read.
[Accept] --> [TLS Handshake] --> [Request Headers] --> [Request Body] --> Response
func SetWriteTimeout ¶
SetWriteTimeout is a time limit imposed on client connecting to the server via http from the time the server has completed reading the request header up to the time it has finished writing the response.
[Accept] --> [TLS Handshake] --> [Request Headers] --> [Request Body] --> Response
func WithCORS ¶
func WithCORS() Option
WithCORS enable the CORS (Cross-Origin Resource Sharing) support.
func WithCtrlC ¶
func WithCtrlC() Option
WithCtrlC enable the internal ctrl+c support from the server.
func WithDocHandlers ¶
func WithDocHandlers(handler ...DocHandler) Option
WithDocHandlers allow to register custom DocHandler struct (ex: swaggo, redoc). If use with SetPrefix, register WithDocHandler after the SetPrefix one. Example:
package main import ( "github.com/burgesQ/webfmwk/v6" "github.com/burgesQ/webfmwk/v6/handler/redoc" ) func main() { var s = webfmwk.InitServer(webfmwk.WithDocHandlers(redoc.GetHandler())) }
func WithHandlers ¶
WithHandlers allow to register a list of webfmwk.Handler Handler signature is the webfmwk.HandlerFunc one (func(c Context)). To register a custom context, simply do it in the toppest handler.
package main import ( "github.com/burgesQ/webfmwk/v6" "github.com/burgesQ/webfmwk/v6/handler/security" ) type CustomContext struct { webfmwk.Context val String } func main() { var s = webfmwk.InitServer(webfmwk.WithHandlers(security.Handler, func(next Habdler) Handler { return func(c webfmwk.Context) error { cc := Context{c, "val"} return next(cc) }}))
func WithSocketHandlerFunc ¶
func WithSocketHandlerFunc(path string, hf http.HandlerFunc) Option
func WithStructuredLogger ¶ added in v6.0.1
WithStructuredLogger set the server structured logger which derive from slog.Logger. Try to set it the earliest possible.
type Response ¶
type Response struct { // Message hold the error message. // // Example: action successfully completed Message string `json:"content,omitempty"` // Status hold the error code status. // // Example: 200 Status int `json:"status" example:"204" validate:"required"` }
Response is returned in case of success.
func NewResponse ¶
NewResponse generate a new Response struct.
func (*Response) SetStatusCode ¶
SetStatusCode set the response status code.
type Route ¶
type Route struct { // Handler hold the exposed Handler method. Handler HandlerFunc `json:"-"` // Verbe hold the verbe at which the handler is reachable. Verbe string `json:"verbe"` // Path hold the uri at which the handler is reachable. // If a prefix is setup, the path will be prefixed. Path string `json:"path"` // Name is used in message. Name string `json:"name"` Middlewares *[]Handler }
Route hold the data for one route.
type RoutesPerPrefix ¶
RoutesPerPrefix hold the routes and there respectiv prefix.
type SendResponse ¶
type SendResponse interface { JSONResponse // SendResponse create & send a response according to the parameters. SendResponse(op int, content []byte, headers ...Header) error // SetHeader set the header of the http response. SetHeaders(headers ...Header) // SetHeader set the k header to value v. SetHeader(k, v string) // SetContentType set the Content-Type to v. SetContentType(v string) // SetContentType set the Content-Type to v. SetStatusCode(code int) // IsPretty toggle the compact output mode. IsPretty() bool }
SendResponse interface is used to reponde content to the client.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a struct holding all the necessary data / struct
func InitServer ¶
InitServer initialize a webfmwk.Server instance. It may take some server options as parameters. List of server options : WithLogger, WithCtrlC, CheckIsUp, WithCORS, SetPrefix, WithHandlers, WithDocHandler, SetReadTimeout, SetWriteTimeout, SetIdleTimeout, EnableKeepAlive. Any error returned by the method should be handled as a fatal one.
func (*Server) ANY ¶
func (s *Server) ANY(path string, handler HandlerFunc)
PATCH expose a handler to the http verb PATCH.
func (*Server) CustomHandler ¶
func (s *Server) CustomHandler(handler HandlerFunc) fasthttp.RequestHandler
CustomHandler return the webfmwk Handler main logic, which return a HandlerFunc wrapper in an fasthttp.Handler.
func (*Server) DELETE ¶
func (s *Server) DELETE(path string, handler HandlerFunc)
DELETE expose a handler to the http verb DELETE.
func (*Server) DisableHTTP2 ¶
DisableHTTP2 allow to disable HTTP2 on the fly. It usage isn't recommanded. For testing purpore only.
func (*Server) DumpRoutes ¶
DumpRoutes dump the API endpoints using the server logger.
func (*Server) EnableCheckIsUp ¶
enableCheckIsUp add an /ping endpoint. If used, once a server is started, the user can check weather the server is up or not by reading the isReady channel vie the IsReady() method.
func (*Server) GET ¶
func (s *Server) GET(path string, handler HandlerFunc)
GET expose a handler to the http verb GET.
func (*Server) GetCancel ¶
func (s *Server) GetCancel() context.CancelFunc
GetContext return the server' context cancel func.
func (*Server) GetContext ¶
GetContext return the context.Context used.
func (*Server) GetLauncher ¶
func (s *Server) GetLauncher() WorkerLauncher
GetLauncher return a pointer to the internal workerLauncher.
func (*Server) GetRouter ¶
GetRouter create a fasthttp/router.Router whit: - registered handlers (webfmwk/v6/handler) - doc handler is registered - test handler (/ping) is registered - registered fmwk routes
func (*Server) GetStructuredLogger ¶ added in v6.0.1
GetLogger return the used Log instance.
func (*Server) PATCH ¶
func (s *Server) PATCH(path string, handler HandlerFunc)
PATCH expose a handler to the http verb PATCH.
func (*Server) POST ¶
func (s *Server) POST(path string, handler HandlerFunc)
POST expose a handler to the http verb POST.
func (*Server) PUT ¶
func (s *Server) PUT(path string, handler HandlerFunc)
PUT expose a handler to the http verb PUT.
func (*Server) RouteApplier ¶
func (s *Server) RouteApplier(rpps ...RoutesPerPrefix)
RouteApplier apply the array of RoutePerPrefix.
func (*Server) Run ¶
Run allow to launch multiple server from a single call. It take an va arg list of Address as argument. The method wait for the server to end via a call to WaitAndStop.
func (*Server) ShutdownAndWait ¶
ShutdownAndWait call for Shutdown and wait for all server to terminate.
func (*Server) StartTLS ¶
StartTLS expose an https server. The server may have mTLS and/or http2 capabilities.
func (*Server) StartUnixSocket ¶ added in v6.0.2
func (*Server) WaitForStop ¶
func (s *Server) WaitForStop()
WaitForStop wait for all servers to terminate. Use of a sync.waitGroup to properly wait all running servers.
type ValidationError ¶
type ValidationError struct { Error ErrorValidation `json:"message"` Status int `json:"status"` }
ValidationError is returned in case of form / query validation error see gtihub.com/go-playground/validator.v10
type WorkerLauncher ¶
type WorkerLauncher interface{ Start(Worker) }
func CreateWorkerLauncher ¶
func CreateWorkerLauncher(wg *sync.WaitGroup, cancel context.CancelFunc) WorkerLauncher
CreateWorkerLauncher initialize and return a WorkerLauncher instance.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package handler implement some extra handler to the webfmwk.
|
Package handler implement some extra handler to the webfmwk. |
cmd
Package webfmwk/v6/tls/cmd hold function destined to be used for command line implementation.
|
Package webfmwk/v6/tls/cmd hold function destined to be used for command line implementation. |