onestrike

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2025 License: MIT Imports: 8 Imported by: 0

README

OneStrike Framework (Go)

A minimal, high-performance Go web framework designed for clarity, speed, and decisive handling of HTTP requests. Inspired by Gin and Echo, OneStrike emphasizes explicit error handling, easy middleware composition, route groups, and ergonomic access to path and query parameters.


Features

  • Routing with HTTP methods: GET, POST, PUT, PATCH, DELETE
  • Route groups with middleware inheritance
  • Global and conditional middleware (use on specific routes or patterns)
  • Explicit error handling via *Response objects
  • Automatic JSON response encoding
  • Panic recovery middleware
  • Profiling middleware with memory stats and execution time
  • Path parameters (/users/:id) via c.Param("id")
  • Query parameters via c.Query("key")
  • Body binding with fail-fast: Bind / BindJSON
  • Optional error-return binding: ShouldBind / ShouldBindJSON

Installation

go get github.com/AscendingHeavens/onestrike

Usage

package main

import (
	"net/http"

	onestrike "github.com/AscendingHeavens/onestrike"
	"github.com/AscendingHeavens/onestrike/middleware"
)

func main() {
	app := onestrike.New()

	// Global middlewares
	app.Use(middleware.Logger())
	app.Use(middleware.Recovery())
	app.Use(middleware.ProfilingMiddleware())

	// Conditional middleware
	app.UseIf("/api/v1/*", AuthMiddleware())

	// Top-level route
	app.GET("/ping", func(c *onestrike.Context) *onestrike.Response {
		return &onestrike.Response{Success: true, Message: "pong", Code: 200}
	})
	app.GET("/search", func(c *onestrike.Context) *onestrike.Response {
		q := c.Query("q")
		return &onestrike.Response{
			Success: true,
			Message: "Query received",
			Details: map[string]string{"query": q},
			Code:    200,
		}
	})

	app.GET("/html", func(c *onestrike.Context) *onestrike.Response {
		return c.HTML(200, "<h1>Serving HTML via OneStrike</h1>") // send file content as HTML
	})

	app.GET("/docs", func(c *onestrike.Context) *onestrike.Response {
		return c.Redirect(302, "https://google.com")
	})

	// Route group
	v1 := app.Group("/api/v1")
	v1.GET("/users/:id", func(c *onestrike.Context) *onestrike.Response {
		id := c.Param("id")
		return &onestrike.Response{Success: true, Message: "User found", Details: map[string]string{"id": id}, Code: 200}
	})

	auth := app.Group("/auth")
	auth.POST("/signup", Signup)
	auth.GET("/users/:id", func(c *onestrike.Context) *onestrike.Response {
		id := c.Param("id")
		return &onestrike.Response{
			Success: true,
			Message: "User found",
			Details: map[string]string{"id": id},
			Code:    200,
		}
	})

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

func AuthMiddleware() onestrike.Middleware {
	return func(next onestrike.HandlerFunc) onestrike.HandlerFunc {
		return func(c *onestrike.Context) *onestrike.Response {
			if c.Request.Header.Get("Authorization") == "" {
				return &onestrike.Response{
					Success: false,
					Message: "Unauthorized",
					Code:    401,
				}
			}
			return next(c)
		}
	}
}

func Signup(ctx *onestrike.Context) *onestrike.Response {
	var req struct{}
	if err := ctx.BindJSON(&req); err != nil {
		return nil
	}
	return &onestrike.Response{
		Message: "Signup successful",
		Success: true,
		Code:    http.StatusOK,
	}
}


Middleware Examples

Logger

Logs request method, path, response status, and execution time.

Recovery

Catches panics and prevents server crash.

Profiling

Logs request duration and memory usage.


Response & Error Handling

Handlers return *onestrike.Response objects:

return &onestrike.Response{
    Success: true,
    Message: "OK",
    Details: map[string]string{"id": id},
    Code: 200,
}

Fail-fast body binding automatically sends 400 Bad Request:

ctx.BindJSON(&req) // on failure, JSON 400 response sent

For custom error handling, use ShouldBindJSON and return your own response.


Query & Path Params

q := c.Query("q")       // /search?q=golang
id := c.Param("id")      // /users/:id

Future Enhancements

  • Form/url-encoded body support
  • Validation helpers
  • More built-in middleware (JWT, etc.)
  • Advanced profiling and metrics
  • Testing

Contributions

Contributions to OneStrike are welcome and encouraged! Here's how you can help:

Reporting Issues
  • Open an issue on GitHub if you find bugs, unexpected behavior, or have feature requests.
  • Provide clear reproduction steps and examples whenever possible.
Code Contributions
  1. Fork the repository.
  2. Create a new branch for your feature or bug fix: git checkout -b feature/my-feature.
  3. Write tests for your changes.
  4. Make your changes following the project's coding standards.
  5. Run all tests locally to ensure nothing breaks.
  6. Commit your changes with clear and descriptive messages.
  7. Push your branch to your fork.
  8. Open a pull request against the main branch of the main repository.
Documentation
  • Improve documentation, examples, or guides.
  • Correct typos or clarify confusing explanations.
Code Reviews
  • Review open pull requests and provide feedback.
  • Test new features and verify fixes.
Style & Standards
  • Follow Go idiomatic practices.
  • Keep commits focused and concise.
  • Write descriptive commit messages.

We appreciate all contributions, big or small, and they help make OneStrike better for everyone!

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConditionalMiddleware

type ConditionalMiddleware = middleware.ConditionalMiddleware

ConditionalMiddleware is an alias to middleware.ConditionalMiddleware, which pairs a pattern (e.g., "/api/*") with a Middleware function.

type Context

type Context = server.Context

Context is an alias to server.Context, which wraps the request and response writer and provides convenience methods (params, body parsing, etc.).

type Group

type Group struct {
	// Prefix is the base path for this group (e.g., "/api/v1").
	Prefix string

	// Server is a reference back to the parent server, allowing
	// groups to register routes directly into the main router.
	Server *Server

	// Middlewares is a list of middleware that will be applied to
	// every route registered within this group, in addition to any
	// global or conditional middleware from the Server.
	Middlewares []middleware.Middleware
}

Group represents a collection of routes that share a common path prefix and middleware stack. Useful for organizing related endpoints like `/api/v1/*`.

func (*Group) DELETE

func (g *Group) DELETE(path string, handler HandlerFunc)

func (*Group) GET

func (g *Group) GET(path string, handler HandlerFunc)

Convenience methods for common HTTP methods for group routes.

func (*Group) Handle

func (g *Group) Handle(method, path string, handler HandlerFunc)

Handle registers a route for the group with a specific HTTP method and path. It automatically prepends the group's prefix to the path and applies the group's middleware stack in reverse order for correct execution.

func (*Group) PATCH

func (g *Group) PATCH(path string, handler HandlerFunc)

func (*Group) POST

func (g *Group) POST(path string, handler HandlerFunc)

func (*Group) PUT

func (g *Group) PUT(path string, handler HandlerFunc)

func (*Group) Use

func (g *Group) Use(mw middleware.Middleware)

Use registers a middleware for this specific group. These middlewares are applied only to routes within the group, in addition to any global middleware from the parent server.

type HandlerFunc

type HandlerFunc = server.HandlerFunc

HandlerFunc is an alias to server.HandlerFunc, the function signature that route handlers must implement. It takes a *Context and returns a *Response.

type Middleware

type Middleware = middleware.Middleware

Middleware is an alias to middleware.Middleware, representing a function that wraps and modifies a HandlerFunc, similar to how middleware works in frameworks like Express or Fiber.

type Response

type Response = server.Response

Response is an alias to server.Response, the unified return type from every handler function. Encoded as JSON and written to the client.

type Server

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

Server is the main entry point for the OneStrike framework. It holds the router, global middlewares, and any conditional middlewares that should be applied based on route patterns.

func New

func New() *Server

New creates a new OneStrike Server instance with an empty router and middleware stack.

func (*Server) DELETE

func (s *Server) DELETE(path string, handler server.HandlerFunc)

func (*Server) GET

func (s *Server) GET(path string, handler server.HandlerFunc)

Convenience methods for each HTTP method.

func (*Server) Group

func (s *Server) Group(prefix string) *Group

Group represents a collection of routes sharing a common prefix and middleware stack. Useful for organizing related endpoints. Example: v1 := app.Group("/api/v1")

func (*Server) Handle

func (s *Server) Handle(method, path string, handler server.HandlerFunc)

Handle registers a route with a specific HTTP method and path. Global middleware is automatically applied in reverse order (so execution order is correct).

func (*Server) PATCH

func (s *Server) PATCH(path string, handler server.HandlerFunc)

func (*Server) POST

func (s *Server) POST(path string, handler server.HandlerFunc)

func (*Server) PUT

func (s *Server) PUT(path string, handler server.HandlerFunc)

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler, so OneStrike Server can be passed directly to http.ListenAndServe. It finds the route, applies conditional middleware, executes the handler, and writes the Response as JSON.

func (*Server) Start

func (s *Server) Start(addr string)

Start runs the HTTP server on the specified address. It logs the startup and will terminate the program if ListenAndServe returns an error.

func (*Server) StartAutoTLS

func (s *Server) StartAutoTLS(domain string)

StartAutoTLS starts the server with automatic TLS certificate management using Let's Encrypt. This method automatically obtains and renews TLS certificates for the specified domain using the ACME protocol. The server will bind to port 443.

Parameters:

  • domain: The domain name for which to obtain certificates (e.g., "example.com")

The method sets up:

  • Automatic certificate cache in a local "certs" directory
  • Automatic acceptance of Let's Encrypt Terms of Service
  • Host whitelist policy for the specified domain
  • TLS configuration with automatic certificate retrieval

Requirements:

  • The server must be accessible from the internet on port 443
  • The domain must point to the server's IP address
  • Port 80 should also be available for ACME challenges (handled automatically by autocert)

This method will call log.Fatal if the server fails to start, terminating the program. Use this for production deployments where server startup failure should halt the application.

Example:

server := &Server{}
server.StartAutoTLS("example.com") // Will serve HTTPS on port 443

func (*Server) StartAutoTLSWithStarter

func (s *Server) StartAutoTLSWithStarter(domain string, starter TLSStarter)

StartAutoTLSWithStarter starts the server with automatic TLS certificate management using a custom TLS starter. This method provides the same automatic certificate functionality as StartAutoTLS but allows dependency injection of the server startup mechanism, making it testable.

Parameters:

  • domain: The domain name for which to obtain certificates (e.g., "example.com")
  • starter: An implementation of TLSStarter interface that handles server startup

This method is primarily intended for testing purposes where you need to mock the server startup behavior. For production use, prefer StartAutoTLS which uses the server's own startup mechanism.

The method configures:

  • autocert.Manager with local certificate caching
  • Automatic TOS acceptance for Let's Encrypt
  • Host policy restricting certificates to the specified domain
  • HTTP server bound to port 443 with TLS configuration

Example:

server := &Server{}
mockStarter := &MockTLSStarter{...}
server.StartAutoTLSWithStarter("example.com", mockStarter)

func (*Server) StartTLS

func (s *Server) StartTLS(addr, certFile, keyFile string)

StartTLS starts the server with TLS using the provided certificate and key files. The server will bind to the specified address and serve HTTPS traffic.

Parameters:

  • addr: The address to bind to (e.g., ":443", "localhost:8443")
  • certFile: Path to the TLS certificate file
  • keyFile: Path to the TLS private key file

This method will call log.Fatal if the server fails to start, terminating the program. Use this for production deployments where server startup failure should halt the application.

Example:

server := &Server{}
server.StartTLS(":443", "/path/to/cert.pem", "/path/to/key.pem")

func (*Server) Use

func (s *Server) Use(mw middleware.Middleware)

Use registers a global middleware that will run on every request.

func (*Server) UseIf

func (s *Server) UseIf(pattern string, mw middleware.Middleware)

UseIf registers a conditional middleware that only runs if the request path matches the given pattern. Patterns can include a wildcard '*' at the end. Example: UseIf("/api/v1/*", AuthMiddleware())

type TLSStarter

type TLSStarter interface {
	// contains filtered or unexported methods
}

First, define an interface for the server starter

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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