cafe

package module
v0.0.0-...-e518a47 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 3 Imported by: 0

README

Cafe ☕

A minimalist HTTP micro-framework for Go, inspired by Nest / Express-style composition with routers and middlewares, but built entirely on top of net/http.

Cafe is designed to:

  • Keep the core small and easy to understand
  • Avoid external dependencies
  • Compose HTTP applications using mounted routers, middlewares, and clear HTTP methods

🎯 Motivation

The Go standard library already provides a solid HTTP foundation, but building structured applications on top of net/http often leads to repetitive boilerplate or early adoption of heavy frameworks.

Cafe exists to fill that gap.

The goal is to offer:

  • A thin abstraction over net/http, not a replacement
  • Familiar composition patterns (routers + middlewares)
  • A codebase small enough to read and understand in one sitting
  • A learning-friendly framework that shows how things work

If you enjoy knowing exactly what happens when a request hits your server, Cafe is for you.


✨ Features

  • ✅ Simple API (Get, Post, Put, Delete)
  • 🧩 Nested routers (routers inside routers)
  • 🧠 Chainable middlewares
  • 🔒 Prevents duplicate routes
  • ⚙️ Based on the standard http.ServeMux
  • 📦 Zero external dependencies

📦 Installation

go get github.com/LucasSim0n/cafe

⚡ Quick Start

package main

import (
    "net/http"
    "github.com/LucasSim0n/cafe"
)

func main() {
    app := cafe.NewServer()

    app.Get("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello Cafe ☕"))
    })

    app.Listen(":3000")
}

🚀 Usage

🛣️ HTTP Routes

Both the server and routers support the basic HTTP methods.

Cafe inherits native path parameter support from net/http (Go 1.22+).

app.Get("/users/{id}", handler)
app.Post("/users", postHandler)
app.Put("/users/{id}", putHandler)
app.Delete("/users/{id}", deleteHandler)

Access parameters:

id := r.PathValue("id")

🧩 Routers
api := cafe.NewRouter()
api.Get("/users", usersHandler)
app.UseRouter("/api", api)

This produces:

GET  /api/users
POST /api/users

🌳 Nested routers

Routers can also contain other routers:

admin := cafe.NewRouter()
admin.Get("/dashboard", dashboardHandler)

api.UseRouter("/admin", admin)

Final result:

GET /api/admin/dashboard

🧠 Middlewares

A middleware is a function that wraps an http.HandlerFunc:

type middleware func(next http.HandlerFunc) http.HandlerFunc
Global middleware
app.Use(func(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.Method, r.URL.Path)
        next(w, r)
    }
})

Applied to all server routes.


Router-level middleware
api.Use(authMiddleware)

Applied only to that router’s routes (and its child routers).


Execution order

Middlewares run in declaration order:

app.Use(mw1)
app.Use(mw2)

Execution flow:

mw1 → mw2 → handler

🔧 Internals (brief)

  • Uses patterns like:

    METHOD /path/{$}
    

    to simulate method-based routing using ServeMux

  • Middlewares are applied:

    • Globally at the App level
    • Locally at each router
  • Routers are resolved recursively


📌 Philosophy

Cafe does not aim to replace larger frameworks.


🤝 Contributing

Contributions are welcome. Keep changes small, focused, and dependency-free.


Built with ❤️ and net/http.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	*Router
	// contains filtered or unexported fields
}

func NewServer

func NewServer() App

func (*App) Listen

func (a *App) Listen(addr string) error

func (*App) ServeHTTP

func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Handler

type Handler = http.Handler

type HandlerFunc

type HandlerFunc = http.HandlerFunc

type Middleware

type Middleware func(next HandlerFunc) HandlerFunc

type Route

type Route struct {
	// contains filtered or unexported fields
}

type Router

type Router struct {
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter(prefix string) *Router

func (*Router) Delete

func (r *Router) Delete(path string, handler HandlerFunc)

func (*Router) Get

func (r *Router) Get(path string, handler HandlerFunc)

func (*Router) Group

func (r *Router) Group(path string) *Router

func (*Router) Post

func (r *Router) Post(path string, handler HandlerFunc)

func (*Router) Put

func (r *Router) Put(path string, handler HandlerFunc)

func (*Router) Use

func (r *Router) Use(mw Middleware)

func (*Router) UseRouter

func (r *Router) UseRouter(child *Router)

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL