Minima 🦄 is a reliable and lightweight framework for Go to carve the web 💻. Developed with core net/http🔌and other native packages, and with 0 dependencies
Please make sure you have Go version 1.15 or higher
mkdir<project-name>&&cd<project-name>gomodinitgithub.com/<user-name>/<repo-name>gogetgithub.com/gominima/minimagorunmain.gopackage main
import"github.com/gominima/minima"funcmain() {
app:=minima.New()
app.Get("/", func(res*minima.Response, req*minima.Request) {
res.OK().Send("Hello World")
})
app.Listen(":3000")
}- Reliable - great modular API for building great server side applications
- Compatible with net/http - use your plain old middlewares written in plain old
net/http - Lightweight - clocked in ~1000 loc
- No Dependency - just your plain old go standard libraries
- Great Documentation - best in class precise documentation
- Auto Docs - docgen for generating all of your routing docs from jsdoc like comments to json or markdown files
Minima's name is inspired by the word minimal and is the motivation for building this framework. As a Golang developer, I was struggling to learn it in my early days due to the steeper learning curve while using net/http.
Also while checking out some other alternate frameworks, I found out that something like fiber wasn't compatible with net/http modules like gqlgen and other middlewares.
Minima solves this problem as it has a very narrow learning curve as well as a robust structure that supports all net/http modules and other middlewares without compromising performance.
Here are some basic examples related to routing and params:
funcUserGetRouter() *minima.Router {
// router instance which would be used by the main routerrouter:=minima.NewRouter()
returnrouter.Get("/user/:id", func(res*minima.Response, req*minima.Request) {
// getting the id parameter from routeid:=req.Param("id")
// instead of adding a param in route, you just need to fetch itusername:=req.Query("name")
// get user from databaseuserdata, err:=db.FindUser(id, username)
iferr!=nil {
// check for errorsres.NotFound().Send("No user found with particular id")
}
// send user datares.OK().Json(userdata)
})
}
funcmain() {
// main minima instanceapp:=minima.New()
// UseRouter method takes minima.router as a param// it appends all the routes used in that specific router to the main instanceapp.UseRouter(UserGetRouter())
// running the app at port 3000app.Listen(":3000")
}funcmain() {
app:=minima.New()
app.Get("/getuser/:id", func(res*minima.Response, req*minima.Request) {
userid:=req.Param("id")
// check if user id is availableifuserid=="" {
res.Error(404, "No user found")
panic("No user id found in request")
}
fmt.Print(userid)
//Will print 20048 from router /getuser/200048
})
}funcmain() {
app:=minima.New()
app.Get("/getuser", func(response*minima.Response, request*minima.Request) {
// query params work a bit differently// instead of adding a param in route, you just need to fetch ituserid:=req.Query("id")
ifuserid=="" {
res.Error(404, "No user found")
panic("No user id found in request")
}
fmt.Print(userid)
// the above will print 20048 from router /getuser?id=20048
})
}Minima is based on a custom implementation of radix tree which makes it extremely performant. The router itself is fully compatible with net/http
typeMinimainterface {
// Minima interface is built over net/http so every middleware is compatible with it// initializes net/http server with addressListen(addressstring) error//static file serve methodsFile(pthstring, dirstring) //serves a single static file to routeStatic(pthstring, dirstring) //serves whole directory with specified pth ex /static/main.html// main handler interfaceServeHTTP(w http.ResponseWriter, q*http.Request)
// main router methodsGet(pathstring, handler...Handler) *minimaPatch(pathstring, handler...Handler) *minimaPost(pathstring, handler...Handler) *minimaPut(pathstring, handler...Handler) *minimaOptions(pathstring, handler...Handler) *minimaHead(pathstring, handler...Handler) *minimaDelete(pathstring, handler...Handler) *minima// takes middlewares as a param and adds them to routes// middlewares initializes before route handler is mountedUse(handlerHandler) *minima//Takes http.Handler and appends it to middleware chainUseRaw(handlerfunc(http.Handler) http.Handler) *minima// an custom handler when route is not matchedNotFound(handlerHandler)*minima// mounts routes to specific base pathMount(basePathstring, router*Router) *minima// takes minima.Router as param and adds the routes from router to main instanceUseRouter(router*Router) *minima// works as a config for minima, you can add multiple middlewares and routers at onceUseConfig(config*Config) *minima// shutdowns the net/http serverShutdown(ctx context.Context) error// prop methodsSetProp(keystring, valueinterface{}) *minimaGetProp(keystring) interface{}
}Both response and request interfaces of minima are written in net/http so you can use any of your old route middlewares in minima out of the box without any hassle.
typeResinterface {
// response interface is built over http.ResponseWriter for easy and better utility// Header methodsGetHeader(keystring) string// gets a header from response bodySetHeader(keystring, valuestring) *Response// sets a new header to response bodyDelHeader(keystring) *Response// Deletes a header from response bodyCloneHeaders() http.Header// clones all headers of the response bodySetlenght(lenstring) *Response// sets content length of the response bodySetBaseHeaders() *Response// sets a good stack of base headers for response bodyFlushHeaders() // flushes headers// utility functions for easier usageSend(contentstring) *Response//send contentWriteBytes(bytes []byte) error//writes bytes to the pageJSON(contentinterface{}) *Response//sends data in json formatXML(contentinterface{}, indentstring) //sends data in xml formatStream(contentType string readio.Reader) // streams content to the routeNoContent(codeint)
Error(statusint, strstring) *Response// this functions returns http.ResponseWriter instance which means you could use any of your alrady written middlewares in minima!Raw() http.ResponseWriter// renders an html file with data to the pageRender(pathstring, datainterface{}) *Response// custom method when there's an errorError(contentinterface{}) *Response// closes io.Writer connection from the routeCloseConn() *Response// redirects to given urlRedirect(urlstring) *Response// sets header statusStatus(codeint) *Response//cookie methodsSetCookie(cookie*http.Cookie) *Response// sets a new cookie to the responseSetCookie(cookie*http.Cookie) *Response// clears a cookie to the response
}
typeReqinterface {
// minima request interface is built on http.Request// returns param from route Param(namestring) string// sets a new param to the request instanceSetParam(keystring, value) string//returns query param from route urlQuery(keystring) string//returns query params to a stringQueryString() string//returns raw url.ValuesQueryParams() url.Values//returns the ip of the request originIP() string//returns whether the request is tls or notIsTLS() bool//returns whether the request is a socket or notIsSocket() bool//returns scheme type of request bodySchemeType() string//Gets form value from request body FormValue(keystring) string//Gets all the form param valuesFormParams() (url.Values, error)
//Gets file from request FormFile(keystring) (*multipart.FileHeader, error)
//Gets request Multipart formMultipartForm() (*multipart.Form, error)
// returns path url from the routePath() string// returns raw request bodyBody() map[string][]string// finds given key value from body and returns itBodyValue(keystring) []string// returns instance of minima.IncomingHeader for incoming header requestsHeader() *IncomingHeader// returns route method ex.get,postMethod() string// Header methodsSetHeader(keystring, valuestring) *Response//sets a new header to request body//Get a header from request bodyGetHeader(keystring) string//Cookie methodsCookies() []*http.Cookie// gets all cookies from request bodyGetCookie(keystring) *http.Cookie// gets a specific cookie from request body
}Minima's middlewares are written in its own custom res and req interfaces in accordance with the standard libraries maintained by Go. You can use res.Raw() to get the http.ResponseWriter instance and req.Raw() to getthe http.Request instance, meaning all community written middlewares are compatible with Minima.
Minima also takes http.Handler while using .UseRaw function and runs it in a chain.
Here is an example of standard net/http middleware being used with minima:
funcMyMiddleWare(res*minima.Response, req*minima.Request) {
w:=res.Raw() // raw http.ResponseWriter instancer:=req.Raw() // raw http.Request instance// your normal net/http middlewarew.Write([]byte(r.URL.Path))
}
app.UseRaw(HttpHandler())If you wanna help grow this project or say a thank you!
- Give minima a GitHub star
- Fork Minima and Contribute
- Write a review or blog on Minima
- Join our Discord community
Thanks to all the contributors, without whom this project would not have been possible:
Be a part of this contribution list by contributing today!
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Copyright (c) 2021-present Apoorv and Contributors. Minima is a Free and Open Source Software licensed under MIT License
