Simple and fast web framework for Go
- Build Status
- GoDoc Reference
- Requirements
- Quick Start
- Starting the webserver
- Configuration options
- Work with config file
- Routing configuration
- Work with logger
Go >= 1.17
go get -u github.com/nexcode/wenex
package main
import (
"io"
"net/http"
"github.com/nexcode/wenex"
)
func first(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello,")
wenex.GetRun(r.Context()).Next()
io.WriteString(w, "!")
}
func second(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, " World")
}
func main() {
config := wenex.DefaultConfig()
config["server.http.listen"] = ":8080"
wnx, err := wenex.New("simpleapp", config, nil)
if err != nil {
panic(err)
}
if err = wnx.Router.StrictRoute("/", "HEAD", "GET").Chain(first, second); err != nil {
panic(err)
}
wnx.Logger("info").Print("running application...")
if err = wnx.Run(); err != nil {
panic(err)
}
}
Open your browser and visit http://localhost:8080
In its simplest form, a webserver can be started like this:
config := wenex.DefaultConfig()
config["server.http.listen"] = ":8080"
wnx, err := wenex.New("simpleapp", config)
if err != nil {
panic(err)
}
// define routing and something else...
if err = wnx.Run(); err != nil {
panic(err)
}
In this simple example:
server.http.listen
- port that will listen to the webserver
simpleapp
- name of the application (a simpleapp.conf
file will be created in the working directory)
config
- configuration options
server.gzip.enable
- enables and disables gzipserver.gzip.level
- gzip compression levelserver.http.listen
- port that will listen to http trafficserver.https.listen
- port that will listen to TLS (https) trafficserver.https.stringCert.cert
- string containing certificateserver.https.stringCert.key
- string containing private keyserver.https.loadCert.cert
- file containing certificateserver.https.loadCert.key
- file containing private keyserver.https.autoCert.hosts
- array of domainsserver.https.autoCert.dirCache
- cache directoryserver.timeout.read
- connection read timeoutserver.timeout.write
- connection write timeoutserver.timeout.idle
- connection idle timeoutlogger.defaultName
- log filename for empty loggerlogger.namePrefix
- prefix that will be added to all saved log files. For example, if you uselog/
prefix, then all logs files will be inlog/
folderlogger.useFlag
- sets the output flags for the logger. The flag bits are Ldate, Ltime, and so onlogger.usePrefix
- string that will be added at the beginning of each message
If you run wenex with this config:
config := wenex.DefaultConfig()
wnx, err := wenex.New("simpleapp", config)
if err != nil {
panic(err)
}
// Some code and wnx.Run()
A config file (simpleapp.conf
) appears in the working directory.
From the config
variable, only missing values will be written to the file.
Overwriting existing values will not occur.
{
"log": {
"filePrefix": "log/"
},
"server": {
"http": {
"listen": ":http"
},
"timeout": {
"idle": "30s",
"read": "30s",
"write": "30s"
}
}
}
You can add any parameters directly to the file or use api:
wnx.Config.Set("key1.key2.keyN", 1000)
err := wnx.Config.Save()
After this, the config file will look like this:
{
"key1": {
"key2": {
"keyN": 1000
}
},
"log": {
"filePrefix": "log/"
},
"server": {
"http": {
"listen": ":http"
},
"timeout": {
"idle": "30s",
"read": "30s",
"write": "30s"
}
}
}
You can get the value of the parameters by api:
valueF64, err := wnx.Config.Float64("key1.key2.keyN")
// Or use it (panic on type error):
// value := wnx.Config.MustFloat64("key1.key2.keyN")
valueStr, err := wnx.Config.String("server.http.listen")
// Or use it (panic on type error):
// value := wnx.Config.MustString("server.http.listen")
// You can get the value as an interface{}
valueInterface := wnx.Config.Get("key")
For the routing declaration in wenex two methods are used:
wnx.Router.StrictRoute(pattern, methods)
- tied to the end of patternwnx.Router.WeakRoute(pattern, methods)
- not tied to the end of pattern
Wenex supports the following special constructs in the pattern:
*
- a sequence of any characters, including the empty string:name
- value of this path element will be available as a value of a get-variable with the same name
Routing declaration returns a method, that allows you to specify multiple handlers:
wnx.Router.StrictRoute(pattern, methods).Chain(handler1, handler2, handlerN)
Matching examples:
wnx.Router.StrictRoute("/*/:var/test/", "HEAD", "GET").Chain(...)
// matching requests:
// /sefsef/aaa/test/
// /zzz/qwe/test/
wnx.Router.WeakRoute("/*/:var/test/", "HEAD", "GET").Chain(...)
// matching requests:
// /sefsef/aaa/test/
// /zzz/zxc/test/rrr/
// /zzz/gg/test/ppp/fff
Chains can run completely sequentially, or you can call the next chain before the first one has completed.
For this, the Next()
method is used.
An example of this behavior is given in the section Simple Example.
Winx creates files with logs dynamically.
It use log.filePrefix
fo path prefix fo all logs files.
For example:
wnx.Logger("file1").Print("some data...")
wnx.Logger("folder2/file2").Print("some data...")
// default log file:
wnx.Logger("").Print("some data...")
You can customize the logger in accordance with the std log.logger
api:
wnx.Logger("").SetPrefix("prefix")