feather

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: May 12, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

README

Feather

Feather is a lightweight, modular HTTP web framework for Go, designed for rapid development of RESTful APIs and web applications. It provides a simple routing system, middleware support, and convenient helpers for handling requests and responses.

Features

  • Routing: Register routes with static and dynamic segments, including custom regex for parameters.
  • Middleware: Add global middleware functions for logging, CORS, authentication, etc.
  • Context: Unified request/response context with helpers for JSON, HTML, files, headers, cookies, and more.
  • Extensible: Easily add custom middlewares and handlers.
  • Minimal Dependencies: Built on Go's standard library.

Getting Started

Installation

Add Feather to your Go project:

go get codeberg.org/esmyx/feather
Basic Usage
package main

import (
    "codeberg.org/esmyx/feather"
    "codeberg.org/esmyx/feather/middlewares"
)

func main() {
    server := feather.NewServer()

    // Add logging and CORS middleware
    server.AddMiddleware(
        middlewares.Logging(),
        middlewares.CORS(
            []string{"*"},
            []string{"GET", "POST", "PUT", "DELETE"},
            []string{"Content-Type"},
        ),
    )

    // Define routes
    server.GET("/", func(c *feather.Context) {
        c.String(200, "Welcome to Feather!")
    })

    server.GET("/user/:id|[0-9]+", func(c *feather.Context) {
        userID := c.Params["id"]
        c.JSON(200, map[string]string{"user_id": userID})
    })

    // Start server
    server.Listen(":8080")
}

Routing

  • Static routes: /about
  • Dynamic routes: /user/:id
  • Dynamic with regex: /post/:slug|[a-z0-9\-]+
  • Wildcard: /files/*path

Middleware

Middlewares are functions that run before the route handler. Use AddMiddleware to register them globally.

Example: Logging and CORS are included in middlewares/.

Context Helpers

  • c.JSON(status, obj) – Send JSON response
  • c.String(status, text) – Send plain text
  • c.HTML(status, html) – Send HTML
  • c.File(status, path) – Send file
  • c.Status(status) – Send status code only
  • c.Redirect(status, url) – Redirect
  • c.SetHeader(key, value) – Set response header
  • c.SetCookie(cookie) – Set cookie
  • c.Query(key) – Get query param
  • c.JSONBody(v) – Parse JSON body
  • c.FormValue(key) – Get form value

License

GNU General Public License v3.0

Documentation

Index

Constants

View Source
const VERSION string = "1.0.0"

Variables

This section is empty.

Functions

This section is empty.

Types

type Context

type Context struct {
	Writer  http.ResponseWriter // Writer is the HTTP response writer used to construct the HTTP response.
	Request *http.Request       // Request is the HTTP request object containing details about the client's request.
	Params  map[string]string   // Params is a map that stores dynamic route parameters extracted from the URL.
	Data    map[string]any      // Data is a map for storing arbitrary key-value pairs, typically used by middleware.
	Logger  Logger
}

Context represents the state and data associated with an HTTP request and response. It provides methods for handling requests, sending responses, and storing data for middleware and handlers.

func (*Context) Abort

func (c *Context) Abort()

Abort halts the execution of any subsequent middleware or handlers. This method should only be used by middlewares.

This function sets the "Abort" key in the Context's Data map to true, signaling that the request processing should be stopped immediately. It does not take any parameters and does not return any value.

func (*Context) Accepts

func (c *Context) Accepts(mime string) bool

Accepts reports whether the client accepts the specified MIME type, based on the request's "Accept" header.

Parameters:

  • mime: The MIME type to check for (e.g., "application/json", "text/html").

Returns:

  • true if the "Accept" header contains the specified MIME type, false otherwise.

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP retrieves the IP address of the client making the request.

This function does not take any parameters.

Returns:

  • A string representing the client's IP address as obtained from the RemoteAddr field of the HTTP request.

func (*Context) ContentType

func (c *Context) ContentType(value string)

ContentType sets the "Content-Type" header for the HTTP response.

Parameters:

  • value: The MIME type to set as the "Content-Type" header value.

This function updates the "Content-Type" header in the HTTP response to the specified MIME type, replacing any existing value.

func (*Context) Cookie

func (c *Context) Cookie(name string) (*http.Cookie, error)

Cookie retrieves a specific cookie from the HTTP request.

Parameters:

  • name: The name of the cookie to retrieve.

Returns:

  • A pointer to an http.Cookie object representing the cookie with the specified name.
  • An error if the cookie is not found or if there is an issue retrieving it.

func (*Context) Download

func (c *Context) Download(path string, filename string)

Download sends a file as an attachment, forcing the browser to download it.

Parameters:

  • path: The file system path of the file to be sent.
  • filename: The name that will be suggested to the client for saving the file.

This function sets the "Content-Disposition" header to "attachment" with the specified filename, then serves the file contents. If the file cannot be opened, it sends a 404 Not Found error response.

func (*Context) Error

func (c *Context) Error(status int, message string)

Error sends an HTTP error response with the specified status code and message.

Parameters:

  • status: The HTTP status code to set for the error response.
  • message: The error message to be sent in the response body.

This function uses the http.Error method to send an error response with the provided status code and message.

func (*Context) File

func (c *Context) File(status int, path string)

File sends the contents of a file as the HTTP response.

Parameters:

  • status: The HTTP status code to set for the response.
  • path: The file system path of the file to be sent.

This function determines the file's MIME type based on its extension, sets the "Content-Type" header accordingly, and writes the file's contents to the response body. If the file cannot be opened, it sends a "404 Not Found" error response.

func (*Context) FileFS

func (c *Context) FileFS(status int, path string, fs fs.FS)

FileFS sends the contents of a file from an embedded or virtual filesystem as the HTTP response.

Parameters:

  • status: The HTTP status code to set for the response.
  • path: The path of the file relative to the provided filesystem.
  • fs: The filesystem (fs.FS) from which the file is read. Typically an embedded filesystem via go:embed, or any fs.FS implementation.

Compared to File(), this function reads the file from the provided fs.FS instead of the host filesystem, making it suitable for embedded assets.

Example:

//go:embed static/*
var staticFiles embed.FS

ctx.FileFS(http.StatusOK, "static/style.css", staticFiles)

If the file cannot be opened, it sends a 404 Not Found error response.

func (*Context) FormValue

func (c *Context) FormValue(key string) string

FormValue parses the request's form data and retrieves the value for the specified key.

Parameters:

  • key: The name of the form field to retrieve the value for.

Returns:

  • The value of the specified form field as a string. If the form field is not present, it returns an empty string. If there is an error parsing the form data, it sends an HTTP 400 Bad Request response and does not return a value.

func (*Context) Get

func (c *Context) Get(key string) any

Get retrieves the value associated with the specified key from the Context's Data map. This method should only be used by middlewares.

Parameters:

  • key: A string representing the key whose associated value is to be retrieved.

Returns:

  • The value associated with the specified key, which can be of any type. If the key does not exist in the Data map, it returns nil.

func (*Context) HTML

func (c *Context) HTML(status int, content string)

HTML sends an HTML response with the specified HTTP status code.

Parameters:

  • status: The HTTP status code to set for the response.
  • content: The HTML content to be sent in the response body.

This function sets the "Content-Type" header to "text/html", writes the HTTP status code to the response, and writes the provided HTML content into the response body.

func (*Context) Header

func (c *Context) Header(key string) string

Header retrieves the value of a specific request header.

Parameters:

  • key: The name of the header to retrieve.

Returns:

  • The value of the specified header as a string. If the header is not present, it returns an empty string.

func (*Context) JSON

func (c *Context) JSON(status int, obj any)

JSON sends a JSON-encoded response with the specified HTTP status code.

Parameters:

  • status: The HTTP status code to set for the response.
  • obj: The object to be JSON-encoded and sent in the response body.

This function sets the "Content-Type" header to "application/json", writes the HTTP status code to the response, and encodes the provided object as JSON into the response body.

func (*Context) JSONBody

func (c *Context) JSONBody(v any) error

JSONBody reads the request body and unmarshals it into the provided structure.

Parameters:

  • v: A pointer to the structure where the JSON data will be unmarshaled.

Returns:

  • An error if reading the body or unmarshaling the JSON fails. If successful, the provided structure is populated with the request data.

func (*Context) MultipartFile

func (c *Context) MultipartFile(key string) (multipart.File, *multipart.FileHeader, error)

MultipartFile retrieves an uploaded file from a multipart form request.

Parameters:

  • key: The name of the form field associated with the uploaded file.

Returns:

  • multipart.File: The uploaded file, ready to be read.
  • *multipart.FileHeader: Metadata about the file, such as its name and size.
  • error: An error if the file cannot be retrieved or the form cannot be parsed.

Example:

file, header, err := c.MultipartFile("avatar")
if err != nil {
    c.Error(http.StatusBadRequest, "Missing file")
    return
}
defer file.Close()

func (*Context) NoContent

func (c *Context) NoContent()

NoContent sends an HTTP 204 No Content response with an empty body.

This function is typically used for DELETE or PUT requests where the server successfully processed the request but has no content to return.

func (*Context) Post

func (c *Context) Post(function HandlerFunc)

Post appends a new handler function to the "PostFunc" middleware chain stored in the Context's Data map. This method should only be used by middlewares.

Parameters:

  • function: A HandlerFunc representing the middleware or handler function to be added to the "PostFunc" chain.

This function retrieves the existing "PostFunc" middleware chain from the Context's Data map, appends the provided handler function to the chain, and updates the "PostFunc" entry in the Data map. It does not return any value.

func (*Context) Query

func (c *Context) Query(key string) string

Query retrieves the value of a query parameter from the URL.

Parameters:

  • key: The name of the query parameter to retrieve.

Returns:

  • The value of the specified query parameter as a string. If the parameter is not present, it returns an empty string.

func (*Context) Redirect

func (c *Context) Redirect(status int, url string)

Redirect sends an HTTP redirect response to the client.

Parameters:

  • status: The HTTP status code to set for the redirect response. Common values include 301 (Moved Permanently) and 302 (Found).
  • url: The target URL to which the client should be redirected.

This function uses the http.Redirect method to send a redirect response with the specified status code and target URL.

func (*Context) Set

func (c *Context) Set(key string, value any)

Set stores a key-value pair in the Context's Data map. This method should only be used by middlewares.

Parameters:

  • key: A string representing the key under which the value will be stored.
  • value: The value to be stored, which can be of any type.

This function does not return any value. It updates the Context's Data map by associating the specified key with the provided value.

func (*Context) SetCookie

func (c *Context) SetCookie(cookie *http.Cookie)

SetCookie adds a Set-Cookie header to the HTTP response.

Parameters:

  • cookie: A pointer to an http.Cookie object that contains the cookie's name, value, and other attributes such as expiration, path, domain, etc.

This function uses the http.SetCookie method to add the specified cookie to the HTTP response. It does not return any value.

func (*Context) SetHeader

func (c *Context) SetHeader(key string, value string)

SetHeader adds a header to the HTTP response.

Parameters:

  • key: The name of the header to set.
  • value: The value to associate with the header.

This function adds the specified header and its value to the HTTP response. If the header already exists, the new value is appended to the existing values.

func (*Context) Status

func (c *Context) Status(status int)

Status sends an HTTP response with the specified status code and an empty body.

Parameters:

  • status: The HTTP status code to set for the response.

This function sets the HTTP status code for the response and writes an empty body.

func (*Context) Stream

func (c *Context) Stream(status int, contentType string, r io.Reader)

Stream sends a streaming response with the specified status code and content type.

Parameters:

  • status: The HTTP status code to set for the response.
  • contentType: The MIME type of the streamed content (e.g., "text/event-stream" for SSE).
  • r: An io.Reader from which the data is read and written to the response body.

This function is useful for sending large files, server-sent events (SSE), or any response where data is produced progressively.

func (*Context) String

func (c *Context) String(status int, s string)

String sends a plain text response with the specified HTTP status code.

Parameters:

  • status: The HTTP status code to set for the response.
  • s: The string content to be sent in the response body.

This function sets the "Content-Type" header to "text/plain", writes the HTTP status code to the response, and writes the provided string content into the response body.

func (*Context) Template

func (c *Context) Template(files []string, data any, funcs template.FuncMap)

Template executes an HTML template with the provided files, data, and custom functions.

Parameters:

  • files: A slice of strings containing the paths to the template files. The first file in the slice is used as the primary template.
  • data: The data to be passed to the template for rendering. Can be of any type that the template can process.
  • funcs: A template.FuncMap containing custom functions that can be used within the template. Can be nil if no custom functions are needed.

This function creates a new template, parses the specified files, and executes the template using the provided data. The rendered output is written to the HTTP response. If any error occurs during template parsing or execution, it sends a 500 Internal Server Error response with the error message.

func (*Context) TemplateFS

func (c *Context) TemplateFS(files []string, data any, funcs template.FuncMap, fs fs.FS)

TemplateFS executes an HTML template from an embedded or virtual filesystem.

Parameters:

  • files: A slice of strings containing the paths to the template files relative to the provided filesystem. The first file in the slice is used as the primary template.
  • data: The data to be passed to the template for rendering. Can be of any type that the template can process.
  • funcs: A template.FuncMap containing custom functions that can be used within the template. Can be nil if no custom functions are needed.
  • fs: The filesystem (fs.FS) from which the template files are read. Typically an embedded filesystem via go:embed, or any fs.FS implementation.

Compared to Template(), this function reads files from the provided fs.FS instead of the host filesystem, making it suitable for embedded assets.

Example:

//go:embed templates/*
var embeddedFiles embed.FS

ctx.TemplateFS(
    []string{"templates/index.html", "templates/base.html"},
    myData,
    nil,
    embeddedFiles,
)

If any error occurs during template parsing or execution, it sends a 500 Internal Server Error response with the error message.

type HandlerFunc

type HandlerFunc func(c *Context)

HandlerFunc represents a function that handles an HTTP request. It takes a single parameter:

  • c: A pointer to the Context, which contains information about the HTTP request, response, and other data.

type Logger

type Logger interface {
	Info(format string, args ...any)
	Error(format string, args ...any)
	Fatal(format string, args ...any)
}
var LoggerToUse Logger = nil

type Route

type Route struct {
	Regex   *regexp.Regexp // Regex is the compiled regular expression used to match the incoming request URL.
	Params  []string       // Params is a list of parameter names extracted from the dynamic segments of the route.
	Handler HandlerFunc    // Handler is the function that will be executed when the route is matched.
}

type Server

type Server struct {
	// routes is a map where the key is the HTTP method (e.g., "GET", "POST") and the value is a slice of Route.
	// Each Route contains the compiled regular expression for matching the URL, the parameter names extracted from the route,
	// and the handler function to execute when the route is matched.
	Routes map[string][]Route

	// middlewares is a slice of HandlerFunc that represents middleware functions.
	// These functions are executed in the order they are added, before the final route handler is called.
	Middlewares []HandlerFunc

	Logger Logger
}

func NewServer

func NewServer() *Server

NewServer creates and initializes a new instance of the Server struct.

This function sets up the Server with an empty map for routes and an empty slice for middlewares. The Server is used to define routes, add middleware, and handle HTTP requests.

Returns:

  • *Server: A pointer to the newly created Server instance.

func (*Server) AddMiddleware

func (server *Server) AddMiddleware(middlewares ...HandlerFunc)

AddMiddleware appends one or more middleware functions to the server's middleware stack.

Middleware functions are executed in the order they are added, before the final route handler is called.

Parameters:

  • middlewares: A variadic parameter of type HandlerFunc. Each HandlerFunc represents a middleware function that takes a pointer to the Context as its argument. These middleware functions can modify the request, response, or context data, and can also decide whether to abort the request processing.

Returns:

  • This function does not return any value.

func (*Server) DELETE

func (server *Server) DELETE(pattern string, handler HandlerFunc)

DELETE registers a new route with the HTTP method "DELETE" and associates it with a specific URL pattern and handler function.

This function is a shorthand for calling the Handle method with the "DELETE" HTTP method. It allows you to define routes that respond to DELETE requests, which are typically used for retrieving data or resources.

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.

Returns:

  • This function does not return any value.

func (*Server) GET

func (server *Server) GET(pattern string, handler HandlerFunc)

GET registers a new route with the HTTP method "GET" and associates it with a specific URL pattern and handler function.

This function is a shorthand for calling the Handle method with the "GET" HTTP method. It allows you to define routes that respond to GET requests, which are typically used for retrieving data or resources.

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.

Returns:

  • This function does not return any value.

func (*Server) Handle

func (server *Server) Handle(pattern string, handler HandlerFunc, methods []string)

Handle registers a new route with the server, associating it with a specific URL pattern, handler function, and one or more HTTP methods.

The function supports dynamic URL segments, which can be defined using a colon (e.g., `/:user`). Custom regular expressions can also be specified for dynamic segments (e.g., `/:id|[0-9]+`).

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.
  • methods ([]string): A slice of HTTP methods (e.g., "GET", "POST") for which this route should be registered. If no methods are provided, the default is ["GET"].

Returns:

  • This function does not return any value.

func (*Server) Listen

func (server *Server) Listen(addr string) error

Listen starts the HTTP server on the specified address and begins handling incoming requests.

This function uses the http.ListenAndServe function from the net/http package to bind the server to the given address and listen for incoming HTTP requests. The Server instance is used as the handler for these requests, routing them to the appropriate middleware and route handlers.

Parameters:

  • addr (string): The address to listen on, in the format "host:port" (e.g., ":8080" for all interfaces on port 8080, or "127.0.0.1:8080" for localhost only).

Returns:

  • error: If the server fails to start or encounters an error, this function returns the error. Otherwise, it blocks indefinitely and does not return.

func (*Server) ListenTLS

func (server *Server) ListenTLS(addr, certFile, keyFile string) error

ListenTLS starts the HTTPS server on the specified address using the provided TLS certificate and key files.

Parameters:

  • addr (string): The address to listen on, in the format "host:port" (e.g., ":443" for all interfaces on port 443).
  • certFile (string): The path to the TLS certificate file (.pem or .crt).
  • keyFile (string): The path to the TLS private key file (.pem or .key).

Returns:

  • error: If the server fails to start or encounters an error, this function returns the error. Otherwise, it blocks indefinitely and does not return.

Example:

err := server.ListenTLS(":443", "cert.pem", "key.pem")

func (*Server) PATCH

func (server *Server) PATCH(pattern string, handler HandlerFunc)

PATCH registers a new route with the HTTP method "PATCH" and associates it with a specific URL pattern and handler function.

This function is a shorthand for calling the Handle method with the "PATCH" HTTP method. It allows you to define routes that respond to PATCH requests, which are typically used for retrieving data or resources.

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.

Returns:

  • This function does not return any value.

func (*Server) POST

func (server *Server) POST(pattern string, handler HandlerFunc)

POST registers a new route with the HTTP method "POST" and associates it with a specific URL pattern and handler function.

This function is a shorthand for calling the Handle method with the "POST" HTTP method. It allows you to define routes that respond to POST requests, which are typically used for retrieving data or resources.

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.

Returns:

  • This function does not return any value.

func (*Server) PUT

func (server *Server) PUT(pattern string, handler HandlerFunc)

PUT registers a new route with the HTTP method "PUT" and associates it with a specific URL pattern and handler function.

This function is a shorthand for calling the Handle method with the "PUT" HTTP method. It allows you to define routes that respond to PUT requests, which are typically used for retrieving data or resources.

Parameters:

  • pattern (string): The URL pattern for the route. It can include static segments, dynamic segments, and optional custom regular expressions for dynamic segments.
  • handler (HandlerFunc): The function to execute when the route is matched. It receives a pointer to the Context, which contains request and response data.

Returns:

  • This function does not return any value.

func (*Server) ServeHTTP

func (server *Server) ServeHTTP(writer http.ResponseWriter, reader *http.Request)

ServeHTTP is the main entry point for handling HTTP requests in the Server.

This function matches incoming HTTP requests against the registered routes based on the HTTP method and URL pattern. If a matching route is found, it creates a Context object, executes middleware functions, and invokes the route's handler. If no matching route is found, it responds with a 404 Not Found status. If the HTTP method is not allowed, it responds with a 405 Method Not Allowed status.

Parameters:

  • writer (http.ResponseWriter): The HTTP response writer used to send data back to the client.
  • reader (*http.Request): The HTTP request object containing details about the incoming request.

Returns:

  • This function does not return any value. It writes the HTTP response directly to the writer.

func (*Server) Static

func (server *Server) Static(prefix string, folderPath string)

Static serves files from a specified folder when the requested URL matches a given prefix.

This function registers a route that maps a URL prefix to a folder on the server's filesystem. When a request is made to a URL that matches the prefix, the server attempts to locate the corresponding file in the specified folder and serves it to the client. The route uses the "GET" HTTP method and supports wildcard paths to serve files dynamically.

Parameters:

  • prefix (string): The URL prefix that maps to the folder. For example, if the prefix is "/static", a request to "/static/file.txt" will attempt to serve "file.txt" from the specified folder.
  • folderPath (string): The path to the folder on the server's filesystem that contains the files to be served.

Returns:

  • This function does not return any value. It registers a route with the server to handle file-serving requests.

func (*Server) StaticFS

func (server *Server) StaticFS(prefix string, folderPath string, fs fs.FS)

StaticFS serves files from an embedded or virtual filesystem when the requested URL matches a given prefix.

Parameters:

  • prefix (string): The URL prefix that maps to the filesystem root. For example, if the prefix is "/static", a request to "/static/style.css" will serve "style.css" from the provided fs.FS.
  • fs (fs.FS): The filesystem from which files are served. Typically an embedded filesystem via go:embed, or any fs.FS implementation.

Compared to Static(), this function reads files from the provided fs.FS instead of the host filesystem, making it suitable for embedded assets.

Example:

//go:embed static/*
var staticFiles embed.FS

server.StaticFS("/static", staticFiles)

If the requested file is not found, a 404 Not Found response is sent.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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