hop

package module
v0.0.27 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2025 License: Apache-2.0 Imports: 20 Imported by: 0

README

Hop - Experimental

⚠️ EXPERIMENTAL: This framework is under active development and the API changes frequently. Not recommended for production use unless you're willing to vendor the code.

Hop is an experimental, modular web application framework for Go, designed for building server-side rendered applications with HTMX integration.

Warning

This is not a general-purpose web framework. It was built for specific use cases and may not suit your needs. Consider using established frameworks like Chi, Echo, Gin, or Fiber for production applications.

Features

  • 🧩 Modular architecture with plugin system
  • 📝 Template rendering with layouts and partials
  • 🔄 Built-in HTMX support
  • 📦 Session management
  • 🎯 Event dispatching
  • 🛣️ HTTP routing with middleware
  • 📋 Configuration management
  • 📝 Structured logging

Quick Start

package main

import (
    "context"
    "log"

    "github.com/patrickward/hop"
    "github.com/patrickward/hop/conf"
    "github.com/patrickward/hop/render"
)

func main() {
    // Create app configuration
    cfg := &hop.AppConfig{
        Config: conf.NewConfig(),
        TemplateSources: render.Sources{
            "": embeddedTemplates,  // Your embedded templates
        },
    }

    // Initialize the app
    app, err := hop.New(cfg)
    if err != nil {
        log.Fatal(err)
    }

    // Register modules
    app.RegisterModule(mymodule.New())

    // Start the app
    if err := app.Start(context.Background()); err != nil {
        log.Fatal(err)
    }
}

Creating a Module

type MyModule struct{}

func New() *MyModule {
    return &MyModule{}
}

func (m *MyModule) ID() string {
    return "mymodule"
}

func (m *MyModule) Init() error {
    return nil
}

Documentation

Overview

Package hop provides an experimental, modular web application framework for Go.

⚠️ Important Notice

This framework is in active development and is currently EXPERIMENTAL.

  • The API is unstable and changes frequently without notice
  • Documentation may be incomplete or outdated
  • Not recommended for production use unless you're willing to vendor the code
  • Built primarily for specific use cases and may not be suitable for general use
  • Limited community support and testing

Consider using established frameworks like Chi, Echo, Gin, or Fiber for production applications.

If you decide to use Hop, be prepared to:

  • Handle breaking changes regularly
  • Read and understand the source code
  • Potentially fork and maintain your own version
  • Contribute fixes and improvements back to the project

What is Hop?

Hop is designed to be a flexible, maintainable web framework that follows Go idioms and best practices. It provides a modular architecture where functionality can be easily extended through a plugin system while maintaining a clean separation of concerns.

Core Features

  • Modular architecture with pluggable components
  • Built-in template rendering with layouts and partials
  • Session management
  • Configuration management
  • Structured logging
  • Event dispatching
  • HTTP routing with middleware support
  • Background task management
  • Graceful shutdown handling

Getting Started

import "github.com/patrickward/hop"

func main() {
	// Create app configuration
	appConfig := hop.AppConfig{
		Config:          &cfg.Hop,
		Logger:          logger,
		TemplateSources: render.Sources{"-": &templates.Files},
		TemplateFuncs:   funcs.NewTemplateFuncMap(authorizer),
		SessionStore:    store,
		Stdout:          stdout,
		Stderr:          stderr,
	}

	// Initialize the app
	app, err := hop.New(cfg)
	if err != nil {
		log.Fatal(err)
	}

	// Register modules
	app.RegisterModule(mymodule.New())

	// Start the app
	if err := app.Start(context.Background()); err != nil {
		log.Fatal(err)
	}
}

Modules

Hop uses a module system to organize and extend functionality. Modules are Go types that implement one or more of the following interfaces:

  • Module (required): Base interface for all modules
  • StartupModule: For modules that need initialization at startup
  • ShutdownModule: For modules that need cleanup at shutdown
  • HTTPModule: For modules that provide HTTP routes
  • DispatcherModule: For modules that handle events
  • TemplateDataModule: For modules that provide template data
  • ConfigurableModule: For modules that require configuration

Creating a basic module:

```go
type MyModule struct {}

func (m *MyModule) ID() string {
    return "mymodule"
}

func (m *MyModule) Init() error {
    return nil
}
```

Template Rendering

Hop includes a template system that supports:

  • Multiple template sources
  • Layout templates
  • Partial templates
  • Custom template functions
  • Automatic template caching
  • HTMX integration

Example template usage:

```go
resp := app.NewResponse(r).
    Layout("main").
    Path("pages/home").
    WithData(map[string]any{
        "Title": "Welcome",
    }).
    StatusOK()
resp.Render(w, r)
```

Configuration

The framework uses a structured configuration system that can be customized:

  • Configuration file support
  • Environment variable overrides
  • Type-safe configuration access

Event System

Hop includes an event dispatcher for loose coupling between components:

  • Publish/subscribe pattern
  • Async event handling
  • Type-safe event definitions
  • Module-specific event handlers

The event system is useful for small, monolithic apps or direct interaction between modules within a single server.

Best Practices

When building applications with Hop:

1. Organize related functionality into modules 2. Use dependency injection via the App container 3. Handle graceful shutdown in modules that need cleanup 4. Use the event system for cross-module communication 5. Implement appropriate interfaces based on module needs 6. Use structured logging for better observability 7. Follow Go idioms and conventions

For more information, see the documentation for individual types and interfaces.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

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

App represents the core application container that manages all framework components. It provides simple dependency injection, module management, and coordinates startup/shutdown of the application. App implements graceful shutdown and ensures modules are started and stopped in the correct order.

func New

func New(cfg AppConfig) (*App, error)

New creates a new application with core components

func (*App) AddChainedRoute

func (a *App) AddChainedRoute(pattern string, handler http.Handler, chain route.Chain)

AddChainedRoute adds a new route to the server with a chain of middleware It takes a pattern, an http.Handler, and a route.Chain struct

func (*App) AddChainedRoutes

func (a *App) AddChainedRoutes(routes map[string]http.Handler, chain route.Chain)

AddChainedRoutes adds multiple routes to the server with a chain of middleware

func (*App) AddRoute

func (a *App) AddRoute(pattern string, handler http.Handler, middleware ...route.Middleware)

AddRoute adds a new route to the server, using the newer v1.22 http.Handler interface. It takes a pattern, an http.Handler, and an optional list of middleware.

func (*App) AddRoutes

func (a *App) AddRoutes(routes map[string]http.Handler, middleware ...route.Middleware)

AddRoutes adds multiple routes to the server. It takes a map of patterns to http.Handlers and an optional list of middleware.

func (*App) Config

func (a *App) Config() *conf.HopConfig

Config returns the configuration for the app

func (*App) Dispatcher added in v0.0.22

func (a *App) Dispatcher() *dispatch.Dispatcher

Dispatcher returns the event bus for the app

func (*App) Error

func (a *App) Error() error

Error returns the first error that occurred during initialization

func (*App) GetModule

func (a *App) GetModule(id string) (Module, error)

GetModule returns a module by ID

func (*App) Logger

func (a *App) Logger() *slog.Logger

Logger returns the logger instance for the app

func (*App) NewResponse

func (a *App) NewResponse(r *http.Request) *render.Response

NewResponse creates a new Response instance with the TemplateManager.

func (*App) NewTemplateData

func (a *App) NewTemplateData(r *http.Request) map[string]any

NewTemplateData returns a map of data that can be used in a Go template, API response, etc. It includes the current user, environment, version, and other useful information.

func (*App) OnShutdown

func (a *App) OnShutdown(fn func(context.Context) error)

OnShutdown registers a function to be called when the app is shutting down

func (*App) OnTemplateData

func (a *App) OnTemplateData(fn OnTemplateDataFunc)

OnTemplateData registers a function that populates template data each time a template is rendered.

func (*App) RegisterModule

func (a *App) RegisterModule(m Module) *App

RegisterModule adds a module to the app

func (*App) Router

func (a *App) Router() *route.Mux

Router returns the router instance for the app

func (*App) RunInBackground

func (a *App) RunInBackground(r *http.Request, fn func() error)

RunInBackground runs a function in the background via the server

func (*App) Session

func (a *App) Session() *scs.SessionManager

Session returns the session manager instance for the app

func (*App) SetErrorTemplate added in v0.0.25

func (a *App) SetErrorTemplate(name string)

SetErrorTemplate sets the template to use for rendering error pages

func (*App) ShutdownServer

func (a *App) ShutdownServer(ctx context.Context) error

ShutdownServer gracefully shuts down the server

func (*App) Start

func (a *App) Start(ctx context.Context) error

Start initializes the app and starts all modules and the server

func (*App) StartModules

func (a *App) StartModules(ctx context.Context) error

StartModules initializes and starts all modules without starting the server

func (*App) Stop

func (a *App) Stop(ctx context.Context) error

Stop gracefully shuts down the app and all modules. This is only called when the server is shutting down.

func (*App) TM

func (a *App) TM() *render.TemplateManager

TM returns the template manager instance for the app

type AppConfig

type AppConfig struct {
	// Config holds the application's configuration settings
	Config *conf.HopConfig
	// Logger is the application's logging instance. If nil, a default logger will be created based on the configuration
	Logger *slog.Logger
	// TemplateSources defines the sources for template files. Multiple sources can be provided with different prefixes
	TemplateSources render.Sources
	// TemplateFuncs merges custom template functions into the default set of functions provided by hop. These are available in all templates.
	TemplateFuncs template.FuncMap
	// TemplateExt defines the extension for template files (default: ".html")
	TemplateExt string
	// SessionStore provides the storage backend for sessions
	SessionStore scs.Store
	// Stdout writer for standard output (default: os.Stdout)
	Stdout io.Writer
	// Stderr writer for error output (default: os.Stderr)
	Stderr io.Writer
}

AppConfig provides configuration options for creating a new App instance. It allows customization of core framework components including logging, template rendering, session management, and I/O configuration.

type ConfigurableModule

type ConfigurableModule interface {
	Module
	// Configure applies the provided configuration to the module
	// The config parameter should be type asserted to the module's
	// specific configuration type
	Configure(ctx context.Context, config any) error
}

ConfigurableModule is implemented by modules that require configuration beyond basic initialization. The Configure method is called after Init but before Start.

type DispatcherModule added in v0.0.22

type DispatcherModule interface {
	Module
	// RegisterEvents registers the module's event handlers with the dispatcher
	RegisterEvents(events *dispatch.Dispatcher)
}

DispatcherModule is implemented by modules that handle application events. The RegisterEvents method is called after initialization to set up any event handlers the module provides.

type HTTPModule

type HTTPModule interface {
	Module
	// RegisterRoutes adds the module's routes to the provided router
	RegisterRoutes(router *route.Mux)
}

HTTPModule is implemented by modules that provide HTTP routes. The RegisterRoutes method is called after module initialization to set up any routes the module provides.

type Module

type Module interface {
	// ID returns a unique identifier for the module
	ID() string

	// Init performs any necessary module initialization
	// It is called when the module is registered with the application
	Init() error
}

Module is the base interface that all modules must implement. It provides identification and initialization capabilities for the module system.

type OnTemplateDataFunc

type OnTemplateDataFunc func(r *http.Request, data *map[string]any)

OnTemplateDataFunc is a function type that takes an HTTP request and a pointer to a map of data. It represents a callback function that can be used to populate data for templates.

type ShutdownModule

type ShutdownModule interface {
	Module
	// Stop performs cleanup actions for the module
	// It should respect the provided context's deadline for graceful shutdown
	Stop(ctx context.Context) error
}

ShutdownModule is implemented by modules that need to perform cleanup actions during application shutdown. Modules are shut down in reverse order of their startup.

type StartupModule

type StartupModule interface {
	Module
	// Start performs startup actions for the module
	// The provided context will be canceled when the application begins shutdown
	Start(ctx context.Context) error
}

StartupModule is implemented by modules that need to perform actions during application startup. The Start method will be called after all modules are initialized but before the HTTP server begins accepting connections.

type TemplateDataModule

type TemplateDataModule interface {
	Module
	// OnTemplateData allows the module to add data to the template context
	// The provided map will be merged with other template data
	OnTemplateData(r *http.Request, data *map[string]any)
}

TemplateDataModule is implemented by modules that provide data to templates. The OnTemplateData method is called for each template render to allow the module to add its data to the template context.

Directories

Path Synopsis
Package conf provides a way to load configuration from JSON files and environment variables, along with a structure to hold the configuration settings for an application and the ability to set up command-line flags for configuration options.
Package conf provides a way to load configuration from JSON files and environment variables, along with a structure to hold the configuration settings for an application and the ability to set up command-line flags for configuration options.
env
Package cookies provides helpers for reading and writing cookies with various security features.
Package cookies provides helpers for reading and writing cookies with various security features.
db
Package db provides database-related helpers and utilities.
Package db provides database-related helpers and utilities.
postgres Module
sqlite_cgo Module
Package dispatch provides a lightweight, type-safe event bus implementation for building event-driven applications in Go.
Package dispatch provides a lightweight, type-safe event bus implementation for building event-driven applications in Go.
internal
Package logger provides some utility methods based around the standard library's slog.Logger package.
Package logger provides some utility methods based around the standard library's slog.Logger package.
Package mail provides a simple mailer that sends emails using the SMTP protocol.
Package mail provides a simple mailer that sends emails using the SMTP protocol.
Package pulse provides standardized metrics collection for hop applications
Package pulse provides standardized metrics collection for hop applications
middleware
Package middleware provides HTTP middleware components for the route package.
Package middleware provides HTTP middleware components for the route package.
secure
password
Package password provides functions for hashing and verifying passwords.
Package password provides functions for hashing and verifying passwords.
Package serve provides a way to create and manage an HTTP server, including routing, middleware, and graceful shutdown.
Package serve provides a way to create and manage an HTTP server, including routing, middleware, and graceful shutdown.
sess

Jump to

Keyboard shortcuts

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