mojito

package module
v1.3.5 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2022 License: MIT Imports: 20 Imported by: 7

README

PRs Welcome

Go-Mojito is a super-modular library to bootstrap your next Go web project. It can be used for strict API-only purposes as well as server-side rendering.

SonarCloud Report


Features

Dependency InjectionRoutingTemplatingLoggingMiddlewareCachingREST Router (beta)

Documentation

Read our GitHub Wiki, check out the Example Project or try run the code below

Icon made with Gopherize and flaticon.


package main

import (
	"github.com/infinytum/go-mojito"
)

var (
	address  = "0.0.0.0:8123"
	cacheKey = "greeting"

	Logger mojito.Logger
	Router mojito.Router
)

func main() {
	Logger = mojito.DefaultLogger()
	Router = mojito.DefaultRouter()

	Logger.Info("Registering application routes...")
	Router.Group("/hello", func(router mojito.Routeable) {
		router.GET("", helloHandler)
		router.GET("/:name", setHelloHandler)
	})

	Logger.Infof("Server has started on %s", address)
	Logger.Error(Router.ListenAndServe(address))
}

type HelloContext struct {
	Cache mojito.Cache `container:"type"`
}

func helloHandler(ctx HelloContext, res *mojito.Response, req *mojito.Request) {
	var name string
	ctx.Cache.GetOrDefault(cacheKey, &name, "world")
	res.String("Hello " + name + "!")
}

func setHelloHandler(ctx HelloContext, res *mojito.Response, req *mojito.Request) {
	var newName = req.ParamOrDefault("name", "world")
	Logger.Field("name", newName).Infof("A new name to greet has been set.")
	ctx.Cache.Set(cacheKey, newName)
	res.String("A new name has been set!")
}

How to use this example code

Once you start this quick example code, a webserver will listen on any IP with the port 8123. On https://localhost:8123/hello you will be greeted with "Hello world!" by default.

To change "world" into something else, you can open https://localhost:8123/hello/yourname and now you will be greeted with whatever name you used.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ResourcesDir is the base path of where all static resources like templates and assets are stored
	// This is dynamically set to the current working directory on startup
	ResourcesDir = ""

	// TemplatePrefix is a prefix that is appended to the ResourcesDir to get the base path for all templates
	// This is used by the default renderer implementation to figure out where to look for partials.
	TemplatePrefix = "/templates/"

	// AssetsPrefix is a prefix that is appended to the ResourcesDir to get the base path for all assets
	// This is used by the provided AssetsHandler implementation to serve files from
	AssetsPrefix = "/assets/"
)
View Source
var ErrorCacheMiss = errors.New("the given key was not found in the cache")

ErrorCacheMiss is returned when the cache could not find the given key

View Source
var (
	// ErrorNotAHandler is returned when an attempt to get a handler from an interface{} failed.
	ErrorNotAHandler = errors.New("Given handler value is not of the type (*)mojito.Handler")
)

Functions

func AssetsDir

func AssetsDir() string

AssetsDir will return the absolute path of the configured assets directory

func AssetsHandler

func AssetsHandler(path string) func(res *Response, req *Request)

AssetsHandler will return a handler that can serve assets on a given path. AssetsHandler will look for the assets as ResourcesDir + AssetsPrefix on the file system. The path provided must be the same path as registered on the router.

func CacheKeyHash

func CacheKeyHash(key string) string

CacheKeyHash returns the SHA256 hash of a string for caching purposes

func DELETE added in v1.3.2

func DELETE(path string, handler interface{}) error

DELETE will add a route to default router for the delete method

func GET added in v1.3.2

func GET(path string, handler interface{}) error

GET will add a route to default router for the get method

func HEAD(path string, handler interface{}) error

HEAD will add a route to default router for the head method

func HandleAssets

func HandleAssets(router Router) error

HandleAssets will register the AssetsHandler on a given router on the default path /assets

func HandleAssetsOnPath

func HandleAssetsOnPath(router Router, path string) error

HandleAssetsOnPath will register the AssetsHandler on a given router and a given path with the correct route param suffix

func ListenAndServe added in v1.3.2

func ListenAndServe(args ...string) error

ListenAndServe will start an HTTP webserver on the given address with the default router

func POST added in v1.3.2

func POST(path string, handler interface{}) error

POST will add a route to default router for the post method

func PUT added in v1.3.2

func PUT(path string, handler interface{}) error

PUT will add a route to default router for the put method

func Register

func Register(resolver interface{}, singleton bool) error

Register will register a new dependency as default for the return type of the function

func RegisterHandlerArgFactory added in v1.3.3

func RegisterHandlerArgFactory[T any](factory HandlerArgFactory)

RegisterHandlerArgFactory will register a factory function for the given generic type which will enable the generic type to be automatically resolved in all handlers.

func RegisterNamed

func RegisterNamed(name string, resolver interface{}, singleton bool) error

RegisterNamed will register a new dependency under the given name

func RegisterRequestType deprecated added in v1.3.0

func RegisterRequestType(reqType reflect.Type, factory introspectObjectFactory[*Request])

RegisterResponseType is the old, not-so-generic register function for new request types

Deprecated: Please use RegisterHandlerArgFactory instead to provide a whole array of custom arguments

func RegisterResponseType deprecated added in v1.3.0

func RegisterResponseType(resType reflect.Type, factory introspectObjectFactory[*Response])

RegisterResponseType is the old, not-so-generic register function for new response types

Deprecated: Please use RegisterHandlerArgFactory instead to provide a whole array of custom arguments

func RequestLogger

func RequestLogger(res *Response, req *Request, next func() error) (err error)

RequestLogger provides a simple middleware implementation that will log every request handled by mojito

func Resolve

func Resolve(obj interface{}) error

Resolve will resolve a dependency based on the target objects type

func ResolveNamed

func ResolveNamed(name string, obj interface{}) error

ResolveNamed will resolve a dependecy based on the given name

func Shutdown added in v1.3.5

func Shutdown() error

Shutdown will stop the HTTP webserver of the default router

func TemplateDir

func TemplateDir() string

TemplateDir will return the absolute path of the configured templates directory

func ViewHandler

func ViewHandler(view string) func(res *Response, req *Request) error

ViewHandler will server a given template using the default rendering engine without any view bag contents

func WithGroup added in v1.3.2

func WithGroup(prefix string, callback func(group RouteGroup)) error

WithGroup will create a new route group for the given prefix on the default router

func WithMiddleware added in v1.3.2

func WithMiddleware(handler interface{}) error

WithMiddleware will add a middleware to the default router

func WithRoute added in v1.3.2

func WithRoute(method RouteMethod, path string, handler interface{}) error

WithRoute will add a new route with the given RouteMethod to the default router

Types

type Cache

type Cache interface {
	// Contains returns whether a key is present in the cache
	Contains(key string) (bool, error)
	// Delete removes a cache entry by its key, will do nothing if the
	// key was not present in the cache
	Delete(key string) error
	// ExpireAfter will mark a cache key for expiration after a certain duration
	ExpireAfter(key string, duration time.Duration) error
	// Get will attempt to read a stored cache value into the given
	// out interface pointer or error if not present
	Get(key string, out interface{}) error
	// Get will attempt to read a stored cache value into the given
	// out interface pointer or return default if not found
	GetOrDefault(key string, out interface{}, def interface{}) error
	// Set will attempt to store a value in the cache with a given key
	Set(key string, val interface{}) error
}

Cache defines the minimum API surface for a valid mojito cache

func DefaultCache

func DefaultCache() (cache Cache)

DefaultCache will return the default cache instance for the mojito.Cache type

func NewMemoryCache

func NewMemoryCache() Cache

NewMemoryCache will create a new instance of the built-in go-mojito memory cache

type DefaultRouteGroup added in v1.3.0

type DefaultRouteGroup struct {
	Middlewares []interface{}
	// contains filtered or unexported fields
}

DefaultRouteGroup is the default implementation of a generic RouteGroup

func (*DefaultRouteGroup) ApplyToRouter added in v1.3.1

func (r *DefaultRouteGroup) ApplyToRouter(router Router, prefix string) error

ApplyToRouter applies all routes in the route group to a given router

func (*DefaultRouteGroup) DELETE added in v1.3.0

func (r *DefaultRouteGroup) DELETE(path string, handler interface{})

DELETE will register a new route using the DELETE method

func (*DefaultRouteGroup) GET added in v1.3.0

func (r *DefaultRouteGroup) GET(path string, handler interface{})

GET will register a new route using the GET method

func (*DefaultRouteGroup) HEAD added in v1.3.0

func (r *DefaultRouteGroup) HEAD(path string, handler interface{})

HEAD will register a new route using the HEAD method

func (*DefaultRouteGroup) POST added in v1.3.0

func (r *DefaultRouteGroup) POST(path string, handler interface{})

POST will register a new route using the POST method

func (*DefaultRouteGroup) PUT added in v1.3.0

func (r *DefaultRouteGroup) PUT(path string, handler interface{})

PUT will register a new route using the PUT method

func (*DefaultRouteGroup) WithMiddleware added in v1.3.0

func (r *DefaultRouteGroup) WithMiddleware(middleware interface{})

WithMiddleware will add a middleware to all registered and future routes in this route group

func (*DefaultRouteGroup) WithRoute added in v1.3.0

func (r *DefaultRouteGroup) WithRoute(method RouteMethod, path string, handler interface{})

WithRoute will add a new route with the given RouteMethod to the route group

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler defines a mojito handler

func GetHandler added in v1.3.0

func GetHandler(handler interface{}) (*Handler, error)

GetHandler will try to cast the given value into a handler, but will fail if the value is not of type (*)mojito.Handler

func NewHandler

func NewHandler(handler interface{}) (*Handler, error)

NewHandler will introspect the given handler and, if valid, return a new handler instance that can serve a route

func (*Handler) AddMiddleware

func (h *Handler) AddMiddleware(middleware interface{}) error

AddMiddleware adds a middleware into the chain

func (Handler) HandlerFunc

func (h Handler) HandlerFunc() HandlerFunc

HandlerFunc will generate the original handlers function without any chained middlewares

func (Handler) Introspection added in v1.3.0

func (h Handler) Introspection() HandlerIntrospection

Introspection will return the introspected information about the handler

func (Handler) Serve

func (h Handler) Serve(req *Request, res *Response) error

Serve is the handler func that executes the handler and all the middlewares

type HandlerArgFactory added in v1.3.3

type HandlerArgFactory func(req *Request, res *Response, next *HandlerFunc) reflect.Value

type HandlerFunc

type HandlerFunc func(res *Response, req *Request) error

HandlerFunc describes the method signature of a mojito handler function that can process an incoming requests. A handler func masks all middleware and dependency injection behind a simple, easy to use interface

func HandlerChain

func HandlerChain(f HandlerFunc, middleware MiddlewareHandler) HandlerFunc

HandlerChain will chain a handler func and a middleware together to form a new, single handler func

type HandlerIntrospection added in v1.3.0

type HandlerIntrospection struct {
	// contains filtered or unexported fields
}

HandlerIntrospection is a structure that contains all introspected details about a (potential) handler

func IntrospectHandler added in v1.3.0

func IntrospectHandler(handler interface{}) *HandlerIntrospection

func (HandlerIntrospection) CanError added in v1.3.0

func (h HandlerIntrospection) CanError() bool

CanError returns true when the handler func is returning error

func (HandlerIntrospection) IsStdlibMiddleware added in v1.3.0

func (h HandlerIntrospection) IsStdlibMiddleware() bool

IsStdlibMiddleware returns true when the handler func is a stdlib middleware

type LogFields

type LogFields map[string]interface{}

LogFields is a type definition for cleaner code

func (LogFields) Clone

func (f LogFields) Clone() LogFields

Clone will clone a map of logfields into a new one

type Logger

type Logger interface {
	// Debug will write a debug log
	Debug(msg interface{})
	// Debugf will write a debug log sprintf-style
	Debugf(msg string, values ...interface{})
	// Error will write a error log
	Error(msg interface{})
	// Errorf will write a error log sprintf-style
	Errorf(msg string, values ...interface{})
	// Fatal will write a fatal log
	Fatal(msg interface{})
	// Fatalf will write a fatal log sprintf-style
	Fatalf(msg string, values ...interface{})
	// Field will add a field to a new logger and return it
	Field(name string, val interface{}) Logger
	// Fields will add multiple fields to a new logger and return it
	Fields(fields LogFields) Logger
	// Info will write a info log
	Info(msg interface{})
	// Infof will write a info log sprintf-style
	Infof(msg string, values ...interface{})
	// Trace will write a trace log
	Trace(msg interface{})
	// Tracef will write a trace log sprintf-style
	Tracef(msg string, values ...interface{})
	// Warn will write a warn log
	Warn(msg interface{})
	// Warnf will write a warn log sprintf-style
	Warnf(msg string, values ...interface{})
}

Logger defines the interface of a mojito compatible logger implementation

func DefaultLogger

func DefaultLogger() (logger Logger)

DefaultLogger will return the default logger instance for the mojito.Logger type

func NewBuiltinLogger

func NewBuiltinLogger() Logger

NewBuiltinLogger will create a new instance of the mojito builtin logger implementation

func NewZerologLogger

func NewZerologLogger() Logger

NewZerologLogger will create a new instance of the mojito zerolog implementation

type MiddlewareHandler

type MiddlewareHandler func(res *Response, req *Request, next interface{}) error

MiddlewareHandler is a special kind of HandlerFunc, that receives the next handler in line as its third parameter.

type Renderer

type Renderer interface {
	// Render will load a template file and render the template
	// within using the viewbag as a context
	Render(view string, bag ViewBag) (string, error)
}

Renderer defines the interface of a mojito compatible renderer

func DefaultRenderer

func DefaultRenderer() (renderer Renderer)

DefaultRenderer will return the default renderer instance for the mojito.Renderer type

func NewHandlebarsRenderer

func NewHandlebarsRenderer() Renderer

NewHandlebarsRenderer will return a new instance of the mojito handlebars renderer implementation

type Request

type Request struct {
	*http.Request
	Params map[string]string
	// contains filtered or unexported fields
}

Request is the mojito implementation of a request which wraps around a regular http.Request object.

func NewRequest

func NewRequest(req *http.Request) *Request

NewRequest will create a new instance of a mojito request for the given http.Request object

func (Request) HasContentType

func (r Request) HasContentType(mimetype string) bool

HasContentType determines whether a request has a given mime type as its content type

func (Request) Metadata

func (r Request) Metadata(key string) string

Metadata returns metadata for this request, if there is any

func (Request) Param

func (r Request) Param(name string) string

Param returns the route parameter or empty string if not found

func (Request) ParamOrDefault

func (r Request) ParamOrDefault(name string, def string) string

ParamOrDefault returns the route parameter or a custom default if not found

func (Request) SetMetadata

func (r Request) SetMetadata(key string, value string)

SetMetadata will set the metadata value for a given key

type Response

type Response struct {
	http.ResponseWriter
	ViewBag ViewBag
}

Response is the mojito implementation of a response which wraps around a regular http.ResponseWriter object

func NewResponse

func NewResponse(res http.ResponseWriter) *Response

NewResponse will create a new instance of a mojito response for the given http.ResponseWriter object

func (Response) JSON

func (r Response) JSON(body interface{}) error

JSON writes any object to the response body as JSON

func (Response) PrettyJSON

func (r Response) PrettyJSON(body interface{}) error

PrettyJSON writes any object to the response body as pretty JSON

func (Response) String

func (r Response) String(body string) error

String will write a string to the response body

func (Response) View

func (r Response) View(view string) error

View will use the default renderer to load a view and render it to the response body using the response object's ViewBag

type RouteGroup

type RouteGroup interface {
	// DELETE will add a route to this route group for the delete method
	DELETE(path string, handler interface{})
	// GET will add a route to this route group for the get method
	GET(path string, handler interface{})
	// HEAD will add a route to this route group for the head method
	HEAD(path string, handler interface{})
	// POST will add a route to this route group for the post method
	POST(path string, handler interface{})
	// PUT will add a route to this route group for the put method
	PUT(path string, handler interface{})

	// WithMiddleware will add a middleware to the route group
	WithMiddleware(handler interface{})
	// WithRoute will add a new route with the given RouteMethod to the route group
	WithRoute(method RouteMethod, path string, handler interface{})

	// ApplyToRouter will attempt to merge all middlewares with the collected route handlers
	// and then attempt to register the routes on the router with a given prefix.
	// Will return an error if any of the steps throw an error
	ApplyToRouter(router Router, prefix string) error
}

RouteGroup defines a structure that groups together a bunch of routes and middleware which can be applied to a router under a common prefix

func NewRouteGroup

func NewRouteGroup() RouteGroup

NewRouteGroup will create a new, empty instance of the default Routeable implementation

type RouteMethod added in v1.3.0

type RouteMethod string

RouteMethod is a string-type for HTTP methods supported by Mojito

const (
	// MethodDelete is the HTTP DELETE method
	MethodDelete RouteMethod = http.MethodDelete

	// MethodGet is the HTTP GET method
	MethodGet RouteMethod = http.MethodGet

	// MethodHead is the HTTP HEAD method
	MethodHead RouteMethod = http.MethodHead

	// MethodPost is the HTTP POST method
	MethodPost RouteMethod = http.MethodPost

	// MethodPut is the HTTP PUT method
	MethodPut RouteMethod = http.MethodPut
)

type Routeable deprecated

type Routeable RouteGroup

Routeable is the old variant of RouteGroup and is deprecated

Deprecated: The Routeable interface has been split into the Router and RouteGroup interface since they share similar methods but not exactly the same ones

type Router

type Router interface {
	// DELETE will add a route to this router for the delete method
	DELETE(path string, handler interface{}) error
	// GET will add a route to this router for the get method
	GET(path string, handler interface{}) error
	// HEAD will add a route to this router for the head method
	HEAD(path string, handler interface{}) error
	// POST will add a route to this router for the post method
	POST(path string, handler interface{}) error
	// PUT will add a route to this router for the put method
	PUT(path string, handler interface{}) error

	// Group is the deprecated version of WithGroup, they do the same thing.
	//
	// Deprecated: For consistency in naming and due to the Routeable interface
	// change, the Group method has been deprecated in favour of WithGroup and
	// its new interface.
	Group(prefix string, callback func(group Routeable)) error

	// WithGroup will create a new route group for the given prefix
	WithGroup(prefix string, callback func(group RouteGroup)) error
	// WithMiddleware will add a middleware to the router
	WithMiddleware(handler interface{}) error
	// WithRoute will add a new route with the given RouteMethod to the router
	WithRoute(method RouteMethod, path string, handler interface{}) error

	// ListenAndServe will start an HTTP webserver on the given address
	ListenAndServe(address string) error

	// Shutdown will stop the HTTP webserver
	Shutdown() error
}

Router defines a superset of a Routeable that can create route groups as well as start a webserver

func DefaultRouter

func DefaultRouter() (router Router)

DefaultRouter will return the default router instance for the mojito.Router type

func NewBunRouter

func NewBunRouter() Router

NewBunRouter will create new instance of the mojito bun router implementation

type ViewBag

type ViewBag map[string]interface{}

ViewBag is a type definition to keep code readable

func (ViewBag) Delete

func (v ViewBag) Delete(key string)

Delete will remove an entry from the ViewBag

func (ViewBag) Set

func (v ViewBag) Set(key string, val interface{})

Set will set a new value for the given key in the ViewBag

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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