sense

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2024 License: MIT, MIT Imports: 31 Imported by: 0

README

Sense

Simple and intuitive Go web framework

IMPORTANT: API is not frozen, bugs expected!

Features

  • CRUD
  • Static files
  • Groups
  • URL, body parser
  • Middlewares
  • Error recovery
  • Auth
  • DBAL
  • Cache
  • Filesystem
  • Localization
  • Data exports
  • Validation
  • Emails
  • Websockets

Examples

Config
config := sense.Config{
    App: config.App{
        Name: "example",
    },
    Cache: config.Cache{
        Memory: memory.New("./cache")
        Redis: redis.New(&redis.Options{...})
    },
    Database: map[string]*quirk.DB{
        sense.Main: quirk.MustConnect(...)
    },
    Export: config.Export{
        Gotenberg: config.Gotenberg{
            Endpoint: "http://localhost:3000",
        },
    },
    Filesystem: filesystem.New(
        context.Background(),
        filesystem.Config{
            Driver: filesystem.Local,
            Dir: "./files"
        },
    ),
    Localization: config.Localization{
        Enabled: true,
        Languages: []config.Language{
            {Main: true, Code: "cs"},
            {Code: "en"},
        },
        Translator: translator.New(
            translator.Config{
                Dir:      "./static/locales",
                FileType: translator.Yaml,
            },
        ),
        Validator: validator.Messages{
            Email:     "error.field.email",
            Required:  "error.field.required",
            MinText:   "error.field.min-text",
            MaxText:   "error.field.max-text",
            MinNumber: "error.field.min-number",
            MaxNumber: "error.field.max-number",
        },
    },
    Router: config.Router{
        Prefix:  "",
        Recover: true,
    },
    Security: config.Security{
        Auth: auth.Config{
          Roles: map[string]auth.Role{
            "owner": {Super: true},
            "sales": {},
          },
          Duration: 24 * time.Hour,
        },
        Firewalls: []config.Firewall{},
    },
    Smtp: mailer.Config{
        Host:     "smtp.example.com",
        Port:     25,
        User:     "exampleuser",
        Password: "examplepass",
    },
}
New instance
app := sense.New(config)
Get
app.Get("/{id}", func(c sense.Context) error {
    var id int
    c.Parse().MustPathValue("id", &id)
    return c.Send().Json(map[string]int{
      "id": id
    })
}) 
Post
app.Post("/", func(c sense.Context) error {
    type example struct {
        Id int `json:"id"`
    } 
    var body example
    c.Parse().MustJson(&body)
    return c.Send().Json(map[string]int{
      "id": body.Id,
    })
}) 
Group
versionOne := app.Group("/v1")
{
    user := versionOne.Group("/user")
    {
        user.Get("/", user_handler.GetAll())
        user.Get("/{id}", user_handler.GetOne())
        user.Post("/", user_handler.CreateOne())
        user.Put("/", user_handler.UpdateOne())
        user.Delete("/{id}", user_handler.RemoveOne())
    }
}
Start an app
app.Run(":8000")

Documentation

Index

Constants

View Source
const (
	LangCookieKey = "X-Lang"
)
View Source
const (
	Main = "main"
)

Variables

View Source
var (
	ErrorInvalidDatabase   = errors.New("invalid database")
	ErrorInvalidWebsocket  = errors.New("invalid websocket")
	ErrorInvalidLang       = errors.New("invalid lang")
	ErrorInvalidMultipart  = errors.New("request has not multipart content type")
	ErrorOpenFile          = errors.New("file cannot be opened")
	ErrorReadData          = errors.New("cannot read data")
	ErrorPointerTarget     = errors.New("target must be a pointer")
	ErrorQueryParamMissing = errors.New("query param is missing")
	ErrorPathValueMissing  = errors.New("path value is missing")
)
View Source
var (
	BlueColor    = lipgloss.NewStyle().Foreground(lipgloss.Color("#60a5fa"))
	EmeraldColor = lipgloss.NewStyle().Foreground(lipgloss.Color("#34d399"))
	WhiteColor   = lipgloss.NewStyle().Foreground(lipgloss.Color("#ffffff"))
)
View Source
var (
	Divider = WhiteColor.Render("------------------------------")
)

Functions

func PathValue

func PathValue[T Assert](c RequestContext, key string, defaultValue ...T) T

func Query

func Query[T Assert](c RequestContext, key string, defaultValue ...T) T

Types

type Assert

type Assert interface {
	string | int | float32 | float64 | bool
}

type Config

type Config struct {
	App          config.App
	Cache        config.Cache
	Database     map[string]*quirk.DB
	Export       config.Export
	Filesystem   filesystem.Config
	Localization config.Localization
	Parser       config.Parser
	Router       config.Router
	Security     config.Security
	Smtp         mailer.Config
}

type Context

type Context interface {
	Auth(dbname ...string) auth.Manager
	Cache() cache.Client
	Cookie() cookie.Cookie
	Config() Config
	Continue() error
	Db(dbname ...string) *quirk.Quirk
	Email() mailer.Mailer
	Export() ExportContext
	Files() filesystem.Client
	Lang() LangContext
	Parse() ParseContext
	Request() RequestContext
	Send() SendContext
	Translate(key string, args ...map[string]any) string
	Validate(s validator.Schema, data any) (bool, ErrorsWrapper[validator.Errors])
}

type ErrorsWrapper

type ErrorsWrapper[T any] struct {
	Errors T `json:"errors"`
}

type ExportContext

type ExportContext interface {
	Csv() exporter.Csv
	Excel() exporter.Excel
	Pdf() exporter.Pdf
}

type Handler

type Handler func(c Context) error

type LangContext

type LangContext interface {
	Exists() bool
	Get() string
	Set(langCode string)
	CreateIfNotExists()
}

type ParseContext

type ParseContext interface {
	QueryParam(key string, target any) error
	PathValue(key string, target any) error
	File(filename string) (form.Multipart, error)
	Files(filesnames ...string) ([]form.Multipart, error)
	Json(target any) error
	Text() (string, error)
	Xml(target any) error
	Url(target any) error

	MustQueryParam(key string, target any)
	MustPathValue(key string, target any)
	MustFile(filename string) form.Multipart
	MustFiles(filesnames ...string) []form.Multipart
	MustJson(target any)
	MustText() string
	MustXml(target any)
	MustUrl(target any)
}

type RequestContext

type RequestContext interface {
	ContentType() string
	Header() http.Header
	Host() string
	Ip() string
	Is() RequestIsContext
	Method() string
	Origin() string
	Path() string
	Protocol() string
	Raw() *http.Request
	UserAgent() string
}

type RequestIsContext

type RequestIsContext interface {
	Get() bool
	Post() bool
	Put() bool
	Patch() bool
	Delete() bool
}

type Route

type Route struct {
	Method    string
	Path      string
	Firewalls []config.Firewall
}

type Router

type Router interface {
	Static(path, dir string) Router
	Use(handler Handler) Router
	Group(pathPrefix string) Router
	Head(path string, handler Handler)
	Get(path string, handler Handler)
	Post(path string, handler Handler)
	Options(path string, handler Handler)
	Put(path string, handler Handler)
	Patch(path string, handler Handler)
	Delete(path string, handler Handler)
	Ws(path, name string, handler Handler)
}

type SendContext

type SendContext interface {
	Header() http.Header
	Status(statusCode int) SendContext
	Error(err any) error
	Text(value string) error
	Html(value string) error
	Bool(value bool) error
	Json(value any) error
	Xml(value string) error
	Redirect(url string) error
	File(name string, bytes []byte) error
	Ws(name string) WsWriter
}

type Sense

type Sense interface {
	Router
	Run(address string)
}

func New

func New(config Config) Sense

type WsWriter

type WsWriter interface {
	Id(id ...int) WsWriter
	Session() WsWriter
	Json(value any) error
	Text(value string) error
}

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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