Skip to content

Repository files navigation

W3 HTTP Framework

Important

The project is currently in BETA. Expect API changes and bugs.

Small framework designed for HTMX-style websites, heavily inspired by Gin.

1 Features

  • Based on HTTPRouter — a high-performance, zero-allocations router.
  • High-performance (benchmarks).
  • Middleware support with method/path based injection & automatic ordering.
  • Static files with caching & checksums.
  • Pre-parsed HTML page rendering.
  • 0% AI (human slop only).

2 Example

The project can be found here

// Custom struct to be stored in w3.Context as user's current session
type User struct {
    Name, Token string
}

// Placeholders
var (
    AuthHolders w3.W3AuthHolders[User]
    IndexPage   w3pages.Holder
)

func init() {
    w3logs.Level = w3logs.LOG_DEBUG
    // Use './www' as root for HTML & static filepaths.
    // Refer to w3pages.UseFS(...) for serving from embeded filesystem
    w3pages.SetFSDir("www")

    // Parse './www/index.html' template and store it for later use in [IndexHandler]
    IndexPage = w3pages.MustLoad("index.html")
}

func main() {
    // Handle 100 concurrent requests
    engine := w3.NewDefault(100)

    // W3Csrf middleware will only inject for state-modifying methods (POST/PUT/etc.)
    engine.Use(w3.W3Csrf(
        func(ctx *w3.Context) string {
            user, authenticated := ctx.Get(AuthHolders.Session)
            if !authenticated {
                return ""
            }
            return user.Token
        },
    ))

    // Use customized session authentication middleware
    AuthHolders = engine.UseCustomized(&w3.W3SessionAuth[User]{
        Cookie:            "session",
        Authenticator:     UserAuthenticator,
        Required:          false,
        IgnoreStaticFiles: true,
    })

    engine.GET("/", IndexHandler)

    engine.
        // Endpoint-specific middleware
        Using(w3.W3MustLogIn()).
        DELETE("/:value", EntityHandler)

    // Serve './www/static/...' files at `/static/*filepath` endpoint
    engine.STATIC("static")

    err := engine.ListenAndServe(":8081")
    if err != nil {
        os.Stderr.WriteString(err.Error())
    }
}

func UserAuthenticator(session_id string) (session User, passed bool) {
    if session_id == "123" {
        return User{Name: "Generic Name", Token: "abc"}, true
    }
    return User{}, false
}

func IndexHandler(ctx *w3.Context) {
    ctx.SendHTML(http.StatusOK, IndexPage, nil)
}

func EntityHandler(ctx *w3.Context) {
    value, _ := ctx.Get(AuthHolders.Session)
    ctx.SendTextf(
        http.StatusOK,
        "Hello %s, authenticated as %#v with valid csrf token!",
        ctx.Params.ByName("value"),
        value,
    )
}

3 Documentation

  • Example projects demonstrate most of the functionality.
  • For implementing your own middleware, refer to w3ware*.go files; the most primitive middleware can be created with w3.FromHandler(...).
  • Respond to the client by using ctx.SendXXX methods.
  • Any variables that need to be passed between middleware use holders that are allocated using w3store.Allocate.

Details can be found in the Go Documentation.

4 Benchmarks

They were performed on projects found under the examples/ directory using the examples/benchmark.sh script.

With the following software & hardware:

OS Arch Linux x86_64
Kernel Linux 7.2.6-arch2-1
CPU Intel® Core™ i5-10300H (8) @ 4.0 GHz
Memory DDR4 15.44 GiB @ 2933 MT/s

4.1 Baseline

Benchmark of a basic pure httprouter endpoint (no W3 library involved).

Running 20s test @ http://localhost:8081/example
  4 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.94ms    1.91ms  21.27ms   86.07%
    Req/Sec    56.39k     4.57k   70.73k    70.38%
  4502095 requests in 20.08s, 562.45MB read
Requests/sec: 224254.39
Transfer/sec:     28.02MB

Result: 4,502,095 requests in 20 seconds (~56.39k requests / second).

4.2 W3

Benchmark of a simple cookie-/header-authenticated endpoint with panic recovery & 200 max concurrent connections.

Running 20s test @ http://localhost:8081/example
  4 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.20ms    2.25ms  31.69ms   86.06%
    Req/Sec    52.62k     4.33k   71.91k    69.12%
  4199157 requests in 20.07s, 592.68MB read
Requests/sec: 209231.46
Transfer/sec:     29.53MB

Result: 4,199,157 requests in 20 seconds (~52.62k requests / second).

About

(Mirror) Small framework designed for HTMX-style websites, heavily inspired by Gin

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages