Help us shape the future of Go! Take the 2026 Go Developer Survey

braza

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2025 License: BSD-3-Clause Imports: 34 Imported by: 0

README

braza

See the Documentation

Features

- File Watcher (hot reload)
- Error management
- Routers
- Schema Validator (with c3po package)
- Rendering built-in (template/html)
- Endpoints
- Implements net/http

- Supports
    - Jwt 
    - Cors 
    - Sessions
    - Websocket
    - Middleware & Next
    - URL Route builder

Simple Example

With a correctly configured Go toolchain:
go get 5tk.dev/braza

main.go

package main

import "5tk.dev/braza"

func main() {
 app := braza.NewApp()
 app.GET("/hello", helloWorld)
 app.GET("/hello/{name}", helloUser) // 'name' is any string
 app.GET("/hello/{userID:int}", userByID) // 'userID' is only int

 fmt.Println(app.Listen())
}

func helloWorld(ctx *braza.Ctx) {
 hello := map[string]any{"Hello": "World"}
 ctx.JSON(hello, 200)
}

func helloUser(ctx *braza.Ctx) {
 rq := ctx.Request   // current Request
 name := rq.PathArgs["name"]
 ctx.HTML("<h1>Hello "+name+"</h1>", 200)
}

func userByID(ctx *braza.Ctx) {
 rq := ctx.Request   // current Request
 id := rq.PathArgs["userID"]
 user := AnyQuery(id)
 ctx.JSON(user, 200)
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrHttpAbort        = errors.New("abort")
	ErrorNotFound       = errors.New("404 Not Found")
	ErrorMethodMismatch = errors.New("405 Method Not Allowed")
)

Functions

func Daemon

func Daemon(apps ...*App) error

func MountSchemaFromRequest

func MountSchemaFromRequest(f *c3po.Fielder, rq *Request) c3po.Schema

func SetCookie

func SetCookie(h http.Header, cookie *http.Cookie)

Set a Cookie. Has the same effect as 'Response.SetCookie'

func SetHeader

func SetHeader(w http.ResponseWriter, h http.Header)

Write the headers in the response

func TypeOf

func TypeOf(obj any) string

Alias of 'fmt.Sprintf("%T", obj)'

Types

type App

type App struct {
	// Main Router
	*Router

	// Main Config
	*Config

	/*
		custom auth parser
			app.BasicAuth = (ctx *braza.Ctx) {
				a := ctx.Request.Header.Get("Authorization")
				if a != ""{
					...
					return user,pass, true
				}
				return "","",false
			}
	*/
	BasicAuth func(*Ctx) (user string, pass string, ok bool) // custom func to parse Authorization Header
	/*
		exec after each request (if the application dont crash)
			app.AfterRequest = (ctx *braza.Ctx) {
				h := ctx.Response.Header()
				h.Set("X-Foo","Bar")
				ctx.Response.SetHeader(h)
				...
			}
	*/
	AfterRequest Func

	/*
		exec before each request
			app.BeforeRequest = (ctx *braza.Ctx) {
				db := database.Open()
				ctx.Global["db"] = db
				user,pass,ok := ctx.Request.BasicAuth()
				if ok {
					ctx.Global["user"] = user
				}
			}
	*/
	BeforeRequest Func

	/*
		exec after close each conn ( this dont has effect in response)
			app.TearDownRequest = (ctx *braza.Ctx) {
				database.Close()
				log.Print(...)
				...
			}
	*/
	TearDownRequest Func

	// The Http.Server
	Srv *http.Server
	// contains filtered or unexported fields
}

func NewApp

func NewApp(cfg *Config) *App

Create a new app with a default settings

app := NewApp(nil) // or NewApp(*braza.Config{})
...
app.Listen()

func (*App) Build

func (app *App) Build(addr ...string)

Build the App, but not start serve

example:

func index(ctx braza.Ctx){}

// it's work
func main() {
	app := braza.NewApp()
	app.GET("/",index)
	app.Build()
	app.UrlFor("index",true)
}
// it's don't work
func main() {
	app := braza.NewApp()
	app.GET("/",index)
	app.UrlFor("index",true)
}

func (*App) ErrorHandler

func (app *App) ErrorHandler(statusCode int, f Func)

Custom Http Error Handler

app.ErrorHandler(401,(ctx *braza.Ctx) {
	ctx.HTML("Access denied",401)
})
app.ErrorHandler(404,(ctx *braza.Ctx) {
	ctx.HTML("Hey boy, you're a little lost",404)
})

func (*App) Listen

func (app *App) Listen(host ...string) (err error)

Start Listener in http

func (*App) ListenTLS

func (app *App) ListenTLS(certFile, certKey string, host ...string) (err error)

Start Listener in https

func (*App) Mount

func (app *App) Mount(routers ...*Router)

Register Router in app

func main() {
	api := braza.NewRouter("api")
	api.post("/products")
	api.get("/products/{productID:int}")

	app := braza.NewApp(nil)
	app.Mount(api)
	// do anything ...
	app.Listen()
}

func (*App) ServeHTTP

func (app *App) ServeHTTP(wr http.ResponseWriter, req *http.Request)

http.Handler

func (*App) ShowRoutes

func (app *App) ShowRoutes()

func (*App) UrlFor

func (app *App) UrlFor(name string, external bool, args ...string) string

Url Builder

app.GET("/users/{userID:int}", index)

app.UrlFor("index", false, "userID", "1"}) //  /users/1
app.UrlFor("index", true, "userID", "1"}) // http://servername/users/1

type Config

type Config struct {
	Env                     string           // environmnt (default 'development')
	SecretKey               string           // for sign session (default ”)
	Servername              string           // for build url routes and route match (default ”)
	ListeningInTLS          bool             // UrlFor return a URl with schema in "https:" (default 'false')
	TemplateFolder          string           // for render Templates Html. Default "templates/"
	TemplateFuncs           template.FuncMap `validate:"-"`
	DisableParseFormBody    bool             // Disable default parse of Request.Form -> if true, use Request.ParseForm()
	DisableTemplateReloader bool             // if app in dev mode, disable template's reload (default false)
	StaticFolder            string           // for serve static files (default '/assets')
	StaticUrlPath           string           // url uf request static file (default '/assets')
	DisableStatic           bool             // disable static endpoint for serving static files (default false)
	Silent                  bool             // don't print logs (default false)
	DisableWarnOn405        bool
	LogFile                 string // save log info in file (default ”)
	DisableFileWatcher      bool   // disable autoreload in dev mode (default false)

	SessionExpires          time.Duration `validate:"-"` // (default 30 minutes)
	SessionPermanentExpires time.Duration `validate:"-"` // (default 31 days)

	SessionPublicKey  *rsa.PublicKey  `validate:"-"`
	SessionPrivateKey *rsa.PrivateKey `validate:"-"`
	// contains filtered or unexported fields
}

func NewConfig

func NewConfig() *Config

Usage:

env := "dev"
devConfig := braza.NewConfig()
prodConfig := braza.NewConfig()
var cfg  *Config

if env == "dev"{
	cfg = devConfig
} else {
	cfg = prodConfig
}
app := braza.NewApp(cfg)
...

func NewConfigFromFile

func NewConfigFromFile(file string) *Config

func (*Config) SetupFromFile

func (c *Config) SetupFromFile(filename string) error

setup config from json, yalm

type Cors

type Cors struct {
	MaxAge string // Access-Control-Max-Age
	// ex:
	//  []string{"example.com","www.example.com"}
	AllowOrigins []string // Access-Control-Allow-Origin
	// ex:
	// 	[]string{"*","GET","POST"}
	AllowMethods []string // Access-Control-Allow-Methods
	// ex:
	// []string{"Authorization","*"}
	AllowHeaders []string // Access-Control-Allow-Headers
	// ex:
	// []string{"X-Header"}
	ExposeHeaders    []string // Access-Control-Expose-Headers
	RequestMethod    string   // Access-Control-Request-Method
	AllowCredentials bool     // Access-Control-Allow-Credentials
	// contains filtered or unexported fields
}

If present on route or router, allows resource sharing between origins

type Ctx

type Ctx struct {
	// Clone Current App
	App *App

	/*
		global variables of current request
			app.BeforeRequest = (ctx *braza.Ctx){
				db := database.Open().Session()
				ctx.Global["db"] = db
				user := db.FindUser()
				ctx.Global["user"] = user

			}
			func index(ctx *braza.Ctx){
				db := ctx.Global["db"].(database.DB)
				user := ctx.Global["user"].(*User)
				...
			}
	*/
	Global map[string]any

	/*
		Current Cookie Session
		func login(ctx *braza.Ctx){
				db := ctx.Global["db"].(database.DB)
				username,pass,ok := ctx.Request.BasicAuth()
				if ok{
					user := &User{}
					db.Where("username = ?",username).Find(user)
					if user.CompareHashPass(pass){
						ctx.Session.Set("user",user.id)
					}
				}
				ctx.Unauthorized()
			}
	*/
	Session *Session

	/*
		Current Response
			func foo(ctx *braza.Ctx) {
				ctx.JSON(map[string]any{
					"foo":"bar",
				}, 200)
			}
			func foo(ctx *braza.Ctx) {
				ctx.HTML("<h1>Hello</h1>",200)
			}
			func foo(ctx *braza.Ctx) {
				ctx.RenderTemplate("index.html")
		  	}
	*/
	*Response

	/*
		Current Request
	*/
	Request *Request

	/*
		New Schema valid from route schema
			Route{
				Url:"/{foo}/{bar:int}"
				Func: foo,
				Schema: &Schema{}
			}

			type Schema struct {
				Bar int `braza:"in=args"`
				Foo string `braza:"in=args"`
				File *braza.File `braza:"in=files"`
				Files []*braza.File `braza:"in=files"`
				XHeader string `braza:"in=headers"`
				User string `braza:"in=auth,name=username"`
				Pass string `braza:"in=auth,name=password"`
				Limit int `braza:"in=query"` // /path/search?limit=1&offset=2
				Offset int `braza:"in=query"` // /path/search?limit=1&offset=2

				Text string `braza:"in=body"`
				Text2 string  // deafult is 'in=body'.
			}

			func foo(ctx *braza.Ctx) {
				sch := ctx.Schema.(*Schema)
				...
			}
	*/
	Schema        Schema
	SchemaFielder *c3po.Fielder

	/*
		Contains information about the current request, route, etc...

		Can only be accessed if there is a match. otherwise the values ​​will be null
			func xpto(ctx *braza.Ctx) {
				route := ctx.Matchinfo.Route
				router := ctx.Matchinfo.Router
				...
			}
	*/
	MatchInfo *MatchInfo
	// contains filtered or unexported fields
}

func CtxForTests

func CtxForTests(app *App, rq *http.Request) *Ctx

func NewCtx

func NewCtx(app *App, wr http.ResponseWriter, rq *http.Request) *Ctx

Returns a new *braza.Ctx

func (*Ctx) Next

func (ctx *Ctx) Next()

executes the next middleware or main function of the request

func (*Ctx) UrlFor

func (ctx *Ctx) UrlFor(name string, external bool, args ...string) string

type File

type File struct {
	Filename     string
	ContentType  string
	ContentLeght int
	Stream       *bytes.Buffer
}

func NewFile

func NewFile(p *multipart.Part) *File

type Func

type Func func(ctx *Ctx)

func Handler

func Handler(h http.Handler) Func

func (Func) String

func (f Func) String() string

type Jsonify

type Jsonify interface {
	ToJson() any
}

type ManyJsonify

type ManyJsonify[C Jsonify] []C

func (ManyJsonify[C]) ToJson

func (mj ManyJsonify[C]) ToJson() any

type ManyMapper

type ManyMapper[C Mapper] []Mapper

func (ManyMapper[C]) ToMap

func (mm ManyMapper[C]) ToMap() []map[string]any

type MapCtrl

type MapCtrl map[string]*Meth

type Mapper

type Mapper interface {
	ToMap() map[string]any
}

type MatchInfo

type MatchInfo struct {
	Func
	Match            bool
	Route            *Route
	Router           *Router
	MethodNotAllowed error
	// contains filtered or unexported fields
}

type Meth

type Meth struct {
	Func          Func
	Schema        Schema
	RespSchema    RespSchema
	SchemaFielder *c3po.Fielder
}

type Request

type Request struct {
	Header http.Header

	Body *bytes.Buffer
	Method,
	RemoteAddr,
	RequestURI,
	ContentType string

	ContentLength int

	URL      *url.URL
	Host     string
	Port     string
	Form     map[string]any
	PathArgs map[string]string
	Mime     map[string]string
	Query    url.Values
	Files    map[string][]*File
	Cookies  map[string]*http.Cookie

	TransferEncoding []string

	Proto      string // "HTTP/1.0"
	ProtoMajor int    // 1
	ProtoMinor int    // 0
	// contains filtered or unexported fields
}

func NewRequest

func NewRequest(req *http.Request, ctx *Ctx) *Request

func (*Request) BasicAuth

func (r *Request) BasicAuth() (username, password string, ok bool)

func (*Request) Clone

func (r *Request) Clone(ctx context.Context) *Request

func (*Request) Context

func (r *Request) Context() context.Context

func (*Request) Ctx

func (r *Request) Ctx() *Ctx

func (*Request) HttpRequest

func (r *Request) HttpRequest() *http.Request

func (*Request) ParseForm

func (r *Request) ParseForm()

func (*Request) ProtoAtLeast

func (r *Request) ProtoAtLeast(major, minor int) bool

func (*Request) Referer

func (r *Request) Referer() string

func (*Request) RequestURL

func (r *Request) RequestURL() string

Returns the current url

func (*Request) UrlFor

func (r *Request) UrlFor(name string, external bool, args ...string) string

URL Builder

app.GET("/", index)
app.GET("/login", login)

app.UrlFor("login", false, "next", "currentUrl"})
// results: /login?next=currentUrl

app.UrlFor("login", true, "token", "foobar"})
// results: http://yourAddress/login?token=foobar

// example
func index(ctx *braza.Ctx) {
	req := ctx.Request
	rsp := ctx.Response
	userID, ok := ctx.Global["user"]
	if !ok {
		next := r.RequestUrl()
		rsp.Redirect(req.UrlFor("login", true, "next", next))
		//  redirect to: http://youraddress/login?next=http://yourhost:port/
	}
	... you code here
}

func (*Request) UserAgent

func (r *Request) UserAgent() string

func (*Request) Websocket

func (r *Request) Websocket() (*websocket.Conn, error)

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

type RespSchema

type RespSchema map[int]any

type Response

type Response struct {
	*bytes.Buffer

	StatusCode int
	// contains filtered or unexported fields
}

func NewResponse

func NewResponse(wr http.ResponseWriter, ctx *Ctx) *Response

func NewResponseForTest

func NewResponseForTest(ctx *Ctx) *Response

func (*Response) Abort

func (r *Response) Abort(code int)

func (*Response) BadRequest

func (r *Response) BadRequest()

func (*Response) CheckErr

func (r *Response) CheckErr(err error)

if err != nil, return a 500 Intenal Server Error

func (*Response) Close

func (r *Response) Close()

func (*Response) Created

func (r *Response) Created()

func (*Response) Forbidden

func (r *Response) Forbidden()

func (*Response) HTML

func (r *Response) HTML(body any, code int)

func (Response) Header

func (r Response) Header() http.Header

func (*Response) Hijack

func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error)

func (*Response) ImATaerpot

func (r *Response) ImATaerpot()

func (*Response) InternalServerError

func (r *Response) InternalServerError()

func (*Response) JSON

func (r *Response) JSON(body any, code int)

func (*Response) MethodNotAllowed

func (r *Response) MethodNotAllowed()

func (*Response) NoContent

func (r *Response) NoContent()

func (*Response) NotFound

func (r *Response) NotFound()

func (*Response) Ok

func (r *Response) Ok()

func (*Response) Redirect

func (r *Response) Redirect(url string)

Redirect to Following URL

func (*Response) RenderTemplate

func (r *Response) RenderTemplate(tmpl string, data ...any)

func (*Response) ServeFile

func (r *Response) ServeFile(pathToFile string)

Serve File

func (*Response) SetCookie

func (r *Response) SetCookie(cookie *http.Cookie)

func (Response) SetHeader

func (r Response) SetHeader(h http.Header)

func (*Response) TEXT

func (r *Response) TEXT(body any, code int)

func (*Response) Unauthorized

func (r *Response) Unauthorized()

func (Response) Write

func (r Response) Write(b []byte) (int, error)

func (Response) WriteHeader

func (r Response) WriteHeader(statusCode int)

type Route

type Route struct {
	/*
		# url patterns
			"" is same "/"
			"/batata"	// match literal "/batata"
			"/{name}"	// match any string (ex: batata1234)
			"/{id:int}"	// match on numbers (ex: 12345)
			"/{path:*}"	|| "/{path:path}" // match anything
			"/{var1:int}/{var2}/{var3}" // is allowed
			`/(\d+)` // regex work too
	*/
	Url string

	// # Route Name
	//	ctx.UrlFor("route Name"...
	Name string

	Func Func

	/*
		allow Cors on this route
		&Cors{
			AllowOrigins: []string{"example.com","www.example.com"},
			AllowMethods: []string{"*","GET","POST"},
			AllowHeaders: []string{"Authorization","*"},
			ExposeHeaders: []string{"X-Header"},
			AllowCredentials: true
		}
	*/
	Cors *Cors

	Schema     Schema
	RespSchema RespSchema

	/*
		# a peculiar way of establishing routes
			Route{
				Name:"foo",
				Url:"/foo",
				MapCtrl: braza.MapCtrl{
					"GET": &braza.Meth{
						Func: Foo,
						Schema: &SchemaFoo{}
					},
					"POST": &braza.Meth{
						Func: Bar,
						Schema: &SchemaBar{}
					},
					"DELETE": &braza.Meth{
						Func: Xpto,
						Schema: &SchemaXpto{}
					},
				},
			}
	*/
	MapCtrl MapCtrl

	// HTTP methods allowed on this route
	//		[]string{"GET","POST","PATCH",...
	Methods []string

	// Func wiil exec before this route
	//		[]Func{	GetUser, HasAUth,...
	Middlewares []Func
	// contains filtered or unexported fields
}

func CONNECT

func CONNECT(url string, f Func) *Route

func DELETE

func DELETE(url string, f Func) *Route

func GET

func GET(url string, f Func) *Route
func HEAD(url string, f Func) *Route

func OPTIONS

func OPTIONS(url string, f Func) *Route

func PATCH

func PATCH(url string, f Func) *Route

func POST

func POST(url string, f Func) *Route

func PUT

func PUT(url string, f Func) *Route

func TRACE

func TRACE(url string, f Func) *Route

func (*Route) GetRouter

func (r *Route) GetRouter() *Router

type Router

type Router struct {
	Cors        *Cors
	Name        string
	Routes      []*Route
	Prefix      string
	Subdomain   string // only {sub} or {sub:int}
	WsUpgrader  *websocket.Upgrader
	Middlewares []Func
	StrictSlash bool
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter(name string) *Router

func (*Router) Add

func (r *Router) Add(url, name string, f Func, meths []string)

func (*Router) AddRoute

func (r *Router) AddRoute(routes ...*Route)

func (*Router) CONNECT

func (r *Router) CONNECT(url string, f Func)

func (*Router) DELETE

func (r *Router) DELETE(url string, f Func)

func (*Router) GET

func (r *Router) GET(url string, f Func)

func (*Router) HEAD

func (r *Router) HEAD(url string, f Func)

func (*Router) OPTIONS

func (r *Router) OPTIONS(url string, f Func)

func (*Router) PATCH

func (r *Router) PATCH(url string, f Func)

func (*Router) POST

func (r *Router) POST(url string, f Func)

func (*Router) PUT

func (r *Router) PUT(url string, f Func)

func (*Router) TRACE

func (r *Router) TRACE(url string, f Func)

type Schema

type Schema any

example:

type Schema struct {
	Bar int `braza:"in=args"`
	File *braza.File `braza:"in=files"`
	Files []*braza.File `braza:"in=files"`
	XHeader string `braza:"in=headers"`
	User string `braza:"in=auth,name=username"`
	Pass string `braza:"in=auth,name=password"`
	Limit int `braza:"in=query"` // /path/search?limit=1&offset=2
	Offset int `braza:"in=query"` // /path/search?limit=1&offset=2

	Text string `braza:"in=body"`
	Text2 string  // deafult is 'in=body'.
}

Route{
	Name:"foo",
	Url:"/{bar:int}",
	Schema: &Schema{},
}

func AnyHandler(ctx *braza.Ctx){
	u := ctx.Schema.(*Schema)
	...
}

type Session

type Session struct {
	Permanent bool
	// contains filtered or unexported fields
}

func (*Session) Del

func (s *Session) Del(key string) string

Delete a Value from Session

func (*Session) Get

func (s *Session) Get(key string) string

Returns a session value based on the key. If key does not exist, returns an empty string

func (*Session) GetSign

func (s *Session) GetSign(ctx *Ctx) (string, error)

Returns a JWT Token from session data

func (*Session) Set

func (s *Session) Set(key, value string)

This inserts a value into the session

Directories

Path Synopsis
examples
api command
reverseProxy command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL