![Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility](https://cdn.sanity.io/images/cgdhsj6q/production/97774ea8c88cc8f4bed2766c31994ebc38116948-1664x1366.png?w=400&fit=max&auto=format)
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
github.com/gookit/rux
Simple and fast web framework for build golang HTTP applications.
RESETFul
or Controller
style structshttp.Handler
interface middlewareNotFound
and NotAllowed
中文说明请看 README.zh-CN
go get github.com/gookit/rux
NOTICE:
v1.3.x
is not fully compatible withv1.2.x
version
package main
import (
"github.com/gookit/rux"
)
func main() {
r := rux.New()
// Add Routes:
r.GET("/", func(c *rux.Context) {
c.Text(200, "hello")
})
r.GET("/hello/{name}", func(c *rux.Context) {
c.Text(200, "hello " + c.Param("name"))
})
r.POST("/post", func(c *rux.Context) {
c.Text(200, "hello")
})
// add multi method support for an route path
r.Add("/post[/{id}]", func(c *rux.Context) {
if c.Param("id") == "" {
// do create post
c.Text(200, "created")
return
}
id := c.Params.Int("id")
// do update post
c.Text(200, "updated " + fmt.Sprint(id))
}, rux.POST, rux.PUT)
// Start server
r.Listen(":8080")
// can also
// http.ListenAndServe(":8080", r)
}
r.Group("/articles", func() {
r.GET("", func(c *rux.Context) {
c.Text(200, "view list")
})
r.POST("", func(c *rux.Context) {
c.Text(200, "create ok")
})
r.GET(`/{id:\d+}`, func(c *rux.Context) {
c.Text(200, "view detail, id: " + c.Param("id"))
})
})
You can add the path params like: {id}
Or {id:\d+}
// can access by: "/blog/123"
r.GET(`/blog/{id:\d+}`, func(c *rux.Context) {
c.Text(200, "view detail, id: " + c.Param("id"))
})
optional params, like /about[.html]
or /posts[/{id}]
:
// can access by: "/blog/my-article" "/blog/my-article.html"
r.GET(`/blog/{title:\w+}[.html]`, func(c *rux.Context) {
c.Text(200, "view detail, id: " + c.Param("id"))
})
r.Add("/posts[/{id}]", func(c *rux.Context) {
if c.Param("id") == "" {
// do create post
c.Text(200, "created")
return
}
id := c.Params.Int("id")
// do update post
c.Text(200, "updated " + fmt.Sprint(id))
}, rux.POST, rux.PUT)
rux support use middleware, allow:
Call priority: global middleware -> group middleware -> route middleware
Examples:
package main
import (
"fmt"
"github.com/gookit/rux"
)
func main() {
r := rux.New()
// add global middleware
r.Use(func(c *rux.Context) {
// do something ...
})
// add middleware for the route
route := r.GET("/middle", func(c *rux.Context) { // main handler
c.WriteString("-O-")
}, func(c *rux.Context) { // middle 1
c.WriteString("a")
c.Next() // Notice: call Next()
c.WriteString("A")
// if call Abort(), will abort at the end of this middleware run
// c.Abort()
})
// add more by Use()
route.Use(func(c *rux.Context) { // middle 2
c.WriteString("b")
c.Next()
c.WriteString("B")
})
// now, access the URI /middle
// will output: ab-O-BA
}
middle 1 -> middle 2 -> main handler -> middle 2 -> middle 1
+-----------------------------+
| middle 1 |
| +----------------------+ |
| | middle 2 | |
start | | +----------------+ | | end
------->| | | main handler | | |--->----
| | |________________| | |
| |______________________| |
|_____________________________|
more please see middleware_test.go middleware tests
rux is support generic http.Handler
interface middleware
You can use
rux.WrapHTTPHandler()
converthttp.Handler
asrux.HandlerFunc
package main
import (
"net/http"
"github.com/gookit/rux"
// here we use gorilla/handlers, it provides some generic handlers.
"github.com/gorilla/handlers"
)
func main() {
r := rux.New()
// create a simple generic http.Handler
h0 := http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
w.Header().Set("new-key", "val")
})
r.Use(rux.WrapHTTPHandler(h0), rux.WrapHTTPHandler(handlers.ProxyHeaders()))
r.GET("/", func(c *rux.Context) {
c.Text(200, "hello")
})
// add routes ...
// Wrap our server with our gzip handler to gzip compress all responses.
http.ListenAndServe(":8000", handlers.CompressHandler(r))
}
package main
import (
"embed"
"net/http"
"github.com/gookit/rux"
)
//go:embed static
var embAssets embed.FS
func main() {
r := rux.New()
// one file
r.StaticFile("/site.js", "testdata/site.js")
// allow any files in the directory.
r.StaticDir("/static", "testdata")
// file type limit in the directory
r.StaticFiles("/assets", "testdata", "css|js")
// go 1.16+: use embed assets. access: /embed/static/some.html
r.StaticFS("/embed", http.FS(embAssets))
}
In rux
, you can add a named route, and you can get the corresponding route instance(rux.Route
) from the router according to the name.
Examples:
r := rux.New()
// Method 1
myRoute := rux.NewNamedRoute("name1", "/path4/some/{id}", emptyHandler, "GET")
r.AddRoute(myRoute)
// Method 2
rux.AddNamed("name2", "/", func(c *rux.Context) {
c.Text(200, "hello")
})
// Method 3
r.GET("/hi", func(c *rux.Context) {
c.Text(200, "hello")
}).NamedTo("name3", r)
// get route by name
myRoute = r.GetRoute("name1")
redirect to other page
r.GET("/", func(c *rux.Context) {
c.AbortThen().Redirect("/login", 302)
})
// Or
r.GET("/", func(c *rux.Context) {
c.Redirect("/login", 302)
c.Abort()
})
r.GET("/", func(c *rux.Context) {
c.Back()
c.Abort()
})
you can quick operate cookies by FastSetCookie()
DelCookie()
Note: You must set or delete cookies before writing BODY content
r.GET("/setcookie", func(c *rux.Context) {
c.FastSetCookie("rux_cookie2", "test-value2", 3600)
c.SetCookie("rux_cookie", "test-value1", 3600, "/", c.Req.URL.Host, false, true)
c.WriteString("hello, in " + c.URL().Path)
})
r.GET("/delcookie", func(c *rux.Context) {
val := ctx.Cookie("rux_cookie") // "test-value1"
c.DelCookie("rux_cookie", "rux_cookie2")
})
code is refer from
julienschmidt/httprouter
package main
import (
"log"
"net/http"
"github.com/gookit/rux"
)
type HostSwitch map[string]http.Handler
// Implement the ServeHTTP method on our new type
func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Check if a http.Handler is registered for the given host.
// If yes, use it to handle the request.
if router := hs[r.Host]; router != nil {
router.ServeHTTP(w, r)
} else {
// Handle host names for which no handler is registered
http.Error(w, "Forbidden", 403) // Or Redirect?
}
}
func main() {
// Initialize a router as usual
router := rux.New()
router.GET("/", Index)
router.GET("/hello/{name}", func(c *rux.Context) {})
// Make a new HostSwitch and insert the router (our http handler)
// for example.com and port 12345
hs := make(HostSwitch)
hs["example.com:12345"] = router
// Use the HostSwitch to listen and serve on port 12345
log.Fatal(http.ListenAndServe(":12345", hs))
}
package main
import (
"log"
"net/http"
"github.com/gookit/rux"
)
type Product struct {
}
// Uses middlewares [optional]
func (Product) Uses() map[string][]rux.HandlerFunc {
return map[string][]rux.HandlerFunc{
// function name: handlers
"Delete": []rux.HandlerFunc{
handlers.HTTPBasicAuth(map[string]string{"test": "123"}),
handlers.GenRequestID(),
},
}
}
// all products [optional]
func (p *Product) Index(c *rux.Context) {
// do something
}
// create product [optional]
func (p *Product) Create(c *rux.Context) {
// do something
}
// save new product [optional]
func (p *Product) Store(c *rux.Context) {
// do something
}
// show product with {id} [optional]
func (p *Product) Show(c *rux.Context) {
// do something
}
// edit product [optional]
func (p *Product) Edit(c *rux.Context) {
// do something
}
// save edited product [optional]
func (p *Product) Update(c *rux.Context) {
// do something
}
// delete product [optional]
func (p *Product) Delete(c *rux.Context) {
// do something
}
func main() {
router := rux.New()
// methods Path Action Route Name
// GET /product index product_index
// GET /product/create create product_create
// POST /product store product_store
// GET /product/{id} show product_show
// GET /product/{id}/edit edit product_edit
// PUT/PATCH /product/{id} update product_update
// DELETE /product/{id} delete product_delete
// resetful style
router.Resource("/", new(Product))
log.Fatal(http.ListenAndServe(":12345", router))
}
package main
import (
"log"
"net/http"
"github.com/gookit/rux"
)
// News controller
type News struct {
}
func (n *News) AddRoutes(g *rux.Router) {
g.GET("/", n.Index)
g.POST("/", n.Create)
g.PUT("/", n.Edit)
}
func (n *News) Index(c *rux.Context) {
// Do something
}
func (n *News) Create(c *rux.Context) {
// Do something
}
func (n *News) Edit(c *rux.Context) {
// Do something
}
func main() {
router := rux.New()
// controller style
router.Controller("/news", new(News))
log.Fatal(http.ListenAndServe(":12345", router))
}
package main
import (
"log"
"net/http"
"github.com/gookit/rux"
)
func main() {
// Initialize a router as usual
router := rux.New()
router.GET(`/news/{category_id}/{new_id:\d+}/detail`, func(c *rux.Context) {
var u = make(url.Values)
u.Add("username", "admin")
u.Add("password", "12345")
b := rux.NewBuildRequestURL()
// b.Scheme("https")
// b.Host("www.mytest.com")
b.Queries(u)
b.Params(rux.M{"{category_id}": "100", "{new_id}": "20"})
// b.Path("/dev")
// println(b.Build().String())
println(c.Router().BuildRequestURL("new_detail", b).String())
// result: /news/100/20/detail?username=admin&password=12345
// get current route name
if c.MustGet(rux.CTXCurrentRouteName) == "new_detail" {
// post data etc....
}
}).NamedTo("new_detail", router)
// Use the HostSwitch to listen and serve on port 12345
log.Fatal(http.ListenAndServe(":12345", router))
}
golint ./...
# list error files
gofmt -s -l ./
# fix format and write to file
gofmt -s -w some.go
go test -cover ./...
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.