Usage
Table of contents
- Quick review
- Handle HTTP Methods
- Match any HTTP method
- Serve static files
- Get route parameters in URL path
- Get query string parameters in URL
- Set response data
- Processing JSON request and send JSON response
Quick review
package main
import (
"fmt"
"time"
"github.com/aisk/vox"
)
func main() {
app := vox.New()
// custom middleware that adds an X-Response-Time header
app.Use(func(ctx *vox.Context, req *vox.Request, res *vox.Response) {
start := time.Now()
ctx.Next()
duration := time.Now().Sub(start)
res.Header.Set("X-Response-Time", fmt.Sprintf("%s", duration))
})
// router param
app.Get("/hello/{name}", func(ctx *vox.Context, req *vox.Request, res *vox.Response) {
res.Body = "Hello, " + req.Params["name"] + "!"
})
// response
app.Get("/", func(ctx *vox.Context, req *vox.Request, res *vox.Response) {
// get the query string
name := req.URL.Query().Get("name")
if name == "" {
name = "World"
}
res.Body = "Hello, " + name + "!"
})
app.Run("localhost:3000")
}
Handle HTTP Methods
package main
import (
"github.com/aisk/vox"
)
func handler(ctx *vox.Context, req *vox.Request, res *vox.Response) {
// Get the current request's HTTP method and put it to the result page.
res.Body = "HTTP Method is: " + req.Method
}
func main() {
app := vox.New()
app.Get("/", handler)
app.Post("/", handler)
app.Put("/", handler)
app.Patch("/", handler)
app.Delete("/", handler)
app.Head("/", handler)
app.Options("/", handler)
app.Trace("/", handler)
// In some cases you may need to handle a custom HTTP method not defined by RFCs, such as FLY.
app.Route("FLY", "/", handler)
app.Run("localhost:3000")
}
Match any HTTP method
You can match all HTTP methods for a path with "*":
package main
import (
"github.com/aisk/vox"
)
func main() {
app := vox.New()
app.Route("*", "/health", func(ctx *vox.Context, req *vox.Request, res *vox.Response) {
res.Body = "ok: " + req.Method
})
app.Run("localhost:3000")
}
Use this pattern for generic endpoints (for example, debug probes). For business APIs, explicit methods (Get, Post, Put, …) are usually clearer.
Serve static files
You can expose a local directory under a URL prefix with static middleware:
package main
import (
"github.com/aisk/vox"
"github.com/aisk/vox/middlewares/static"
)
func main() {
app := vox.New()
// Serve files in ./public under /assets
// GET /assets/logo.png -> ./public/logo.png
app.Use(static.Middleware("/assets", "./public"))
app.Run("localhost:3000")
}
Get route parameters in URL path
package main
import (
"github.com/aisk/vox"
)
func hello(ctx *vox.Context, req *vox.Request, res *vox.Response) {
name := req.Params["name"]
res.Body = "Hello, " + name + "!"
}
func main() {
app := vox.New()
app.Get("/hello/{name}", hello)
app.Run("localhost:3000")
}
Get query string parameters in URL
package main
import (
"github.com/aisk/vox"
)
func hello(ctx *vox.Context, req *vox.Request, res *vox.Response) {
name := req.URL.Query().Get("name")
res.Body = "Hello, " + name + "!"
}
func main() {
app := vox.New()
app.Get("/hello", hello)
app.Run("localhost:3000")
}
Set response data
package main
import (
"github.com/aisk/vox"
)
func towel(ctx *vox.Context, req *vox.Request, res *vox.Response) {
// Set the response body, it can be a string, []byte, or anything that json.Marshal accepts.
res.Body = "new towel is created!"
// Set the response status code.
res.Status = 201
// Set the response header.
res.Header.Set("Location", "/towels/42")
}
func main() {
app := vox.New()
app.Post("/towels", towel)
app.Run("localhost:3000")
}
Processing JSON request and send JSON response
package main
import (
"encoding/json"
"net/http"
"strings"
"github.com/aisk/vox"
)
type Error struct {
Code int `json:"code"`
Message string `json:"message"`
}
type Towel struct {
Color string `json:"color"`
Size string `json:"size"`
}
func towel(ctx *vox.Context, req *vox.Request, res *vox.Response) {
if !strings.HasPrefix(req.Header.Get("Content-Type"), "application/json") {
res.Status = http.StatusUnsupportedMediaType // or just 415
// Set the body with a map, vox will marshal it to JSON automatically for you.
res.Body = map[string]interface{}{
"code": 1,
"message": "This is not a JSON request",
}
return
}
var t Towel
if err := json.NewDecoder(req.Body).Decode(&t); err != nil {
res.Status = http.StatusUnprocessableEntity // or just 422
res.Body = map[string]interface{}{
"code": 1,
}
}
// Set the body with a struct, vox will marshal it to JSON automatically for you.
res.Body = t
// Set the response status code.
res.Status = 201
// Set the response header.
res.Header.Set("Location", "/towels/42")
}
func main() {
app := vox.New()
app.Post("/towels", towel)
app.Run("localhost:3000")
}