{"id":36531503,"url":"https://github.com/joakimcarlsson/go-router","last_synced_at":"2026-03-06T09:13:56.703Z","repository":{"id":277391554,"uuid":"929309063","full_name":"JoakimCarlsson/go-router","owner":"JoakimCarlsson","description":"A lightweight HTTP router for Go with built-in OpenAPI 3.0 support, featuring route grouping, middleware support, and type-safe request/response documentation.","archived":false,"fork":false,"pushed_at":"2025-12-26T09:13:26.000Z","size":266,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"dev","last_synced_at":"2025-12-27T21:11:05.121Z","etag":null,"topics":["go","http-router","rest-api"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoakimCarlsson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-08T08:39:44.000Z","updated_at":"2025-12-26T09:13:30.000Z","dependencies_parsed_at":"2025-12-26T11:11:02.421Z","dependency_job_id":null,"html_url":"https://github.com/JoakimCarlsson/go-router","commit_stats":null,"previous_names":["joakimcarlsson/go-router"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/JoakimCarlsson/go-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoakimCarlsson%2Fgo-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoakimCarlsson%2Fgo-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoakimCarlsson%2Fgo-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoakimCarlsson%2Fgo-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoakimCarlsson","download_url":"https://codeload.github.com/JoakimCarlsson/go-router/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoakimCarlsson%2Fgo-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28332841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","http-router","rest-api"],"created_at":"2026-01-12T03:01:34.603Z","updated_at":"2026-01-12T03:01:40.050Z","avatar_url":"https://github.com/JoakimCarlsson.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Router\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/JoakimCarlsson/go-router.svg)](https://pkg.go.dev/github.com/JoakimCarlsson/go-router)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Go Version](https://img.shields.io/badge/Go-%3E%3D%201.22-blue.svg)](https://golang.org/dl/)\n[![Go Report Card](https://goreportcard.com/badge/github.com/joakimcarlsson/go-router)](https://goreportcard.com/report/github.com/joakimcarlsson/go-router)\n\nA high-performance, modular HTTP router for Go with built-in **OpenAPI 3.0** and **Swagger UI** support.\n\n## Features\n\n- **Auto Documentation**: Built-in OpenAPI 3.0 spec generation with type safety\n- **Interactive UI**: Integrated Swagger UI for API exploration and testing\n- **Modular Design**: Use only what you need - core routing or full documentation stack\n- **Standard Compatible**: Works with any `http.Handler` middleware from the ecosystem\n- **Modern Go**: Built for Go 1.22+ with new routing patterns and features\n- **Type Safe**: Compile-time type safety for request/response documentation\n- **Server-Sent Events**: Built-in SSE support for real-time applications\n- **File Uploads**: Multipart form handling with validation\n- **Content Negotiation**: Automatic JSON/XML response selection\n- **Route Groups**: Organize routes with prefixes and shared middleware\n- **Custom Types**: Register custom OpenAPI schemas for your types\n\n## Overview\n\nThis router is designed with modularity in mind, allowing you to use only the components you need. The project is structured into several packages, each with a specific responsibility:\n\n### Core Packages\n\n- **router**: The core HTTP routing functionality\n  - Path parameter support\n  - Middleware support\n  - Router groups\n  - HTTP method helpers\n  - Multipart form data handling\n  - File upload support\n\n- **middleware**: Built-in middleware components\n  - CORS middleware with extensive configuration options\n  - Support for custom headers, origins, and methods\n  - Wildcard support for domain matching\n\n- **metadata**: Shared type definitions\n  - OpenAPI/Swagger shared types\n  - OAuth2 configuration\n  - Common utilities\n  - Custom type handler registry\n\n### Documentation Packages\n\n- **docs**: API documentation utilities\n  - Type-safe route documentation\n  - Request/response schema generation\n  - Parameter and security documentation\n  - Validation tag support\n  - Custom type schema generation\n\n- **openapi**: OpenAPI specification generation\n  - OpenAPI 3.0 support\n  - Schema generation from Go types\n  - Security scheme configuration\n  - Server and info configuration\n\n- **swagger**: Swagger UI configuration and serving\n  - Customizable UI\n  - Dark mode support\n  - OAuth2 configuration\n  - Custom CSS/JS support\n\n### Integration\n\n- **integration**: Component integration\n  - OpenAPI adapter\n  - Swagger UI integration\n  - Clean separation of concerns\n\n## Installation\n\n```bash\ngo get github.com/joakimcarlsson/go-router\n```\n\n## Quick Start\n\n### Basic HTTP Server\n\n```go\npackage main\n\nimport (\n    \"github.com/joakimcarlsson/go-router/router\"\n    \"log\"\n)\n\nfunc main() {\n    r := router.New()\n    \n    // Simple routes\n    r.GET(\"/\", func(c *router.Context) {\n        c.JSON(200, map[string]string{\"message\": \"Hello, World!\"})\n    })\n    \n    r.GET(\"/users/{id}\", func(c *router.Context) {\n        userID := c.Param(\"id\")\n        c.JSON(200, map[string]string{\"user_id\": userID})\n    })\n    \n    // Start server\n    log.Fatal(r.Run(\":8080\"))\n}\n```\n\n### With Auto-Generated API Documentation\n\n```go\npackage main\n\nimport (\n    \"github.com/joakimcarlsson/go-router/router\"\n    \"github.com/joakimcarlsson/go-router/docs\"\n    \"github.com/joakimcarlsson/go-router/integration\"\n    \"log\"\n)\n\ntype User struct {\n    ID    string `json:\"id\"`\n    Name  string `json:\"name\"`\n    Email string `json:\"email\"`\n}\n\ntype ErrorResponse struct {\n    Error string `json:\"error\"`\n}\n\nfunc main() {\n    r := router.New()\n    \n    // Setup auto-documentation\n    err := integration.Setup(r, integration.SetupOptions{\n        Title:       \"My API\",\n        Version:     \"1.0.0\",\n        Description: \"A sample API with auto-generated documentation\",\n        SpecPath:    \"/openapi.json\",\n        DocsPath:    \"/docs\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    \n    // Documented route with type safety\n    r.GET(\"/users/{id}\", getUser,\n        docs.WithSummary(\"Get user by ID\"),\n        docs.WithDescription(\"Retrieves a user by their unique identifier\"),\n        docs.WithTags(\"Users\"),\n        docs.WithPathParam(\"id\", \"string\", true, \"User ID\", \"123\"),\n        docs.WithJSONResponse[User](200, \"User found\"),\n        docs.WithJSONResponse[ErrorResponse](404, \"User not found\"),\n    )\n    \n    log.Printf(\"Server starting on :8080\")\n    log.Printf(\"API docs available at: http://localhost:8080/docs\")\n    log.Fatal(r.Run(\":8080\"))\n}\n\nfunc getUser(c *router.Context) {\n    id := c.Param(\"id\")\n    user := User{ID: id, Name: \"John Doe\", Email: \"john@example.com\"}\n    c.JSON(200, user)\n}\n```\n\n## Comprehensive Examples\n\n### RESTful API with Full Documentation\n\n```go\npackage main\n\nimport (\n    \"strconv\"\n    \"time\"\n    \n    \"github.com/joakimcarlsson/go-router/router\"\n    \"github.com/joakimcarlsson/go-router/docs\"\n    \"github.com/joakimcarlsson/go-router/integration\"\n)\n\ntype Task struct {\n    ID          int       `json:\"id\"`\n    Title       string    `json:\"title\"`\n    Description string    `json:\"description\"`\n    Completed   bool      `json:\"completed\"`\n    CreatedAt   time.Time `json:\"created_at\"`\n    UpdatedAt   time.Time `json:\"updated_at\"`\n}\n\ntype CreateTaskRequest struct {\n    Title       string `json:\"title\" validate:\"required\"`\n    Description string `json:\"description\"`\n}\n\ntype UpdateTaskRequest struct {\n    Title       *string `json:\"title,omitempty\"`\n    Description *string `json:\"description,omitempty\"`\n    Completed   *bool   `json:\"completed,omitempty\"`\n}\n\nfunc main() {\n    r := router.New()\n    \n    // Setup documentation\n    integration.Setup(r, integration.SetupOptions{\n        Title:       \"Task Manager API\",\n        Version:     \"1.0.0\",\n        Description: \"A RESTful API for managing tasks\",\n    })\n    \n    // API routes with documentation\n    api := r.Group(\"/api/v1\", func(api *router.Router) {\n        api.WithTags(\"Tasks\")\n        \n        // List tasks\n        api.GET(\"/tasks\", listTasks,\n            docs.WithSummary(\"List all tasks\"),\n            docs.WithQueryParam(\"completed\", \"boolean\", false, \"Filter by completion status\", nil),\n            docs.WithQueryParam(\"limit\", \"integer\", false, \"Number of tasks to return\", 10),\n            docs.WithJSONResponse[[]Task](200, \"List of tasks\"),\n        )\n        \n        // Create task\n        api.POST(\"/tasks\", createTask,\n            docs.WithSummary(\"Create a new task\"),\n            docs.WithJSONRequestBody[CreateTaskRequest](true, \"Task data\"),\n            docs.WithJSONResponse[Task](201, \"Task created\"),\n            docs.WithJSONResponse[ErrorResponse](400, \"Invalid input\"),\n        )\n        \n        // Get task\n        api.GET(\"/tasks/{id}\", getTask,\n            docs.WithSummary(\"Get task by ID\"),\n            docs.WithPathParam(\"id\", \"integer\", true, \"Task ID\", 1),\n            docs.WithJSONResponse[Task](200, \"Task found\"),\n            docs.WithJSONResponse[ErrorResponse](404, \"Task not found\"),\n        )\n        \n        // Update task\n        api.PUT(\"/tasks/{id}\", updateTask,\n            docs.WithSummary(\"Update a task\"),\n            docs.WithPathParam(\"id\", \"integer\", true, \"Task ID\", 1),\n            docs.WithJSONRequestBody[UpdateTaskRequest](true, \"Updated task data\"),\n            docs.WithJSONResponse[Task](200, \"Task updated\"),\n            docs.WithJSONResponse[ErrorResponse](404, \"Task not found\"),\n        )\n        \n        // Delete task\n        api.DELETE(\"/tasks/{id}\", deleteTask,\n            docs.WithSummary(\"Delete a task\"),\n            docs.WithPathParam(\"id\", \"integer\", true, \"Task ID\", 1),\n            docs.WithResponse(204, \"Task deleted\"),\n            docs.WithJSONResponse[ErrorResponse](404, \"Task not found\"),\n        )\n    })\n    \n    r.Run(\":8080\")\n}\n\n// Handler implementations\nfunc listTasks(c *router.Context) {\n    completed := c.QueryBoolDefault(\"completed\", false)\n    limit := c.QueryIntDefault(\"limit\", 10)\n    \n    // Implementation here\n    c.JSON(200, []Task{})\n}\n\nfunc createTask(c *router.Context) {\n    var req CreateTaskRequest\n    if err := c.BindJSON(\u0026req); err != nil {\n        c.JSON(400, ErrorResponse{Error: \"Invalid JSON\"})\n        return\n    }\n    \n    // Implementation here\n    task := Task{\n        ID:          1,\n        Title:       req.Title,\n        Description: req.Description,\n        CreatedAt:   time.Now(),\n        UpdatedAt:   time.Now(),\n    }\n    c.JSON(201, task)\n}\n\nfunc getTask(c *router.Context) {\n    id, err := strconv.Atoi(c.Param(\"id\"))\n    if err != nil {\n        c.JSON(400, ErrorResponse{Error: \"Invalid task ID\"})\n        return\n    }\n    \n    // Implementation here\n    c.JSON(200, Task{ID: id})\n}\n\nfunc updateTask(c *router.Context) {\n    id, err := strconv.Atoi(c.Param(\"id\"))\n    if err != nil {\n        c.JSON(400, ErrorResponse{Error: \"Invalid task ID\"})\n        return\n    }\n    \n    var req UpdateTaskRequest\n    if err := c.BindJSON(\u0026req); err != nil {\n        c.JSON(400, ErrorResponse{Error: \"Invalid JSON\"})\n        return\n    }\n    \n    // Implementation here\n    c.JSON(200, Task{ID: id})\n}\n\nfunc deleteTask(c *router.Context) {\n    id, err := strconv.Atoi(c.Param(\"id\"))\n    if err != nil {\n        c.JSON(400, ErrorResponse{Error: \"Invalid task ID\"})\n        return\n    }\n    \n    // Implementation here\n    c.Status(204)\n}\n```\n\n## CORS Middleware\n\nConfigure Cross-Origin Resource Sharing (CORS) with the built-in middleware:\n\n```go\nimport (\n    \"github.com/joakimcarlsson/go-router/router\"\n    \"github.com/joakimcarlsson/go-router/router/middleware/cors\"\n)\n\nfunc main() {\n    r := router.New()\n    \n    // Use default CORS settings (allow all origins)\n    r.Use(cors.Default())\n    \n    // Or use custom CORS configuration with the simple API\n    r.Use(cors.Handler(cors.Options{\n        AllowOrigins:     []string{\"https://example.com\", \"https://*.trusted-domain.com\"},\n        AllowMethods:     []string{http.MethodGet, http.MethodPost, http.MethodPut},\n        AllowHeaders:     []string{\"Origin\", \"Content-Type\", \"Authorization\"},\n        ExposeHeaders:    []string{\"Content-Length\", \"X-Request-ID\"},\n        AllowCredentials: true,\n        MaxAge:           86400, // Cache preflight response for 24 hours\n    }))\n    \n    // Different CORS settings for specific route groups\n    r.Group(\"/api\", func(api *router.Router) {\n        api.Use(cors.Handler(cors.Options{\n            AllowOrigins: []string{\"https://api.example.com\"},\n            // Other options...\n        }))\n        \n        // API routes...\n    })\n}\n```\n\n## Standard Middleware Compatibility\n\nThe router exclusively uses standard HTTP middleware, making it compatible with the vast ecosystem of existing Go middleware:\n\n```go\nimport (\n    \"github.com/joakimcarlsson/go-router/router\"\n    \"github.com/justinas/nosurf\"  // Example of a standard middleware package\n)\n\nfunc main() {\n    r := router.New()\n    \n    // Use any standard HTTP middleware\n    r.Use(loggingMiddleware, cors.Default())\n    \n    // Standard middleware is any function with signature:\n    // func(http.Handler) http.Handler\n    \n    // Convert a standard http.Handler to a router.HandlerFunc\n    fileServer := http.FileServer(http.Dir(\"./static\"))\n    r.GET(\"/static/*filepath\", router.FromHTTPHandler(fileServer))\n    \n    // Convert a router.HandlerFunc to a standard http.HandlerFunc\n    customHandler := func(c *router.Context) {\n        c.JSON(200, map[string]string{\"message\": \"Hello\"})\n    }\n    \n    // Use with standard http package\n    http.Handle(\"/api/hello\", router.ToHTTPHandlerFunc(customHandler))\n}\n```\n\n## File Uploads\n\nHandle file uploads with built-in multipart form support:\n\n```go\n// Define your upload struct with form tags\ntype FileUpload struct {\n    File        *multipart.FileHeader `form:\"file\" file:\"true\" required:\"true\" description:\"The file to upload\"`\n    Name        string                `form:\"name\" description:\"Optional name for the file\"`\n    Description string                `form:\"description\" description:\"Description of the file\"`\n}\n\n// Handle single file upload\nr.POST(\"/upload\", func(c *router.Context) {\n    var upload FileUpload\n    if err := c.BindForm(\u0026upload); err != nil {\n        c.JSON(400, map[string]string{\"error\": err.Error()})\n        return\n    }\n\n    // Save the file\n    dst := filepath.Join(\"uploads\", upload.File.Filename)\n    if err := c.SaveUploadedFile(upload.File, dst); err != nil {\n        c.JSON(500, map[string]string{\"error\": err.Error()})\n        return\n    }\n\n    c.JSON(201, map[string]string{\n        \"message\": \"File uploaded successfully\",\n        \"name\": upload.Name,\n        \"path\": dst,\n    })\n})\n\n// Configure upload size limit\nr.WithMultipartConfig(32 \u003c\u003c 20) // 32 MB\n```\n\n## Documentation Support\n\nAdd OpenAPI documentation to your routes:\n\n```go\nimport \"github.com/joakimcarlsson/go-router/docs\"\n\n// Document a JSON endpoint\nr.GET(\"/users/{id}\", getUser,\n    docs.WithSummary(\"Get user by ID\"),\n    docs.WithPathParam(\"id\", \"string\", true, \"User ID\", nil),\n    docs.WithJSONResponse[User](200, \"User found\"),\n)\n\n// Document a file upload endpoint\nr.POST(\"/upload\", uploadHandler,\n    docs.WithSummary(\"Upload a file\"),\n    docs.WithMultipartFormStruct[FileUpload](\"File upload with metadata\"),\n    docs.WithJSONResponse[UploadResponse](201, \"File uploaded successfully\"),\n)\n```\n\n## Custom Type Handlers\n\nRegister custom OpenAPI schema handlers for your own types:\n\n```go\nimport (\n    \"reflect\"\n    \"github.com/joakimcarlsson/go-router/metadata\"\n)\n\n// Define a custom type\ntype EmailAddress string\n\n// Register a type handler\nmetadata.RegisterTypeHandler(\"mypackage.EmailAddress\", func(t reflect.Type) metadata.Schema {\n    return metadata.Schema{\n        Type:        \"string\",\n        Format:      \"email\",\n        Example:     \"user@example.com\",\n        Description: \"Email address in standard format\",\n    }\n})\n\n// Use it in your models\ntype User struct {\n    Email EmailAddress `json:\"email\"`\n    // Other fields...\n}\n```\n\n## Swagger UI Integration\n\nAdd interactive API documentation:\n\n```go\nimport (\n    \"github.com/joakimcarlsson/go-router/integration\"\n    \"github.com/joakimcarlsson/go-router/openapi\"\n    \"github.com/joakimcarlsson/go-router/swagger\"\n)\n\n// Create OpenAPI generator\ngenerator := openapi.NewGenerator(openapi.Info{\n    Title:   \"My API\",\n    Version: \"1.0.0\",\n})\n\n// Configure Swagger UI\nswaggerUI := integration.NewSwaggerUIIntegration(r, generator)\nswaggerUI.SetupRoutes(r, \"/openapi.json\", \"/docs\")\n```\n\n## Advanced Features\n\n### File Uploads\n\n```go\ntype FileUpload struct {\n    File        *multipart.FileHeader `form:\"file\" file:\"true\" required:\"true\"`\n    Name        string                `form:\"name\"`\n    Description string                `form:\"description\"`\n}\n\nr.POST(\"/upload\", func(c *router.Context) {\n    var upload FileUpload\n    if err := c.BindForm(\u0026upload); err != nil {\n        c.JSON(400, map[string]string{\"error\": err.Error()})\n        return\n    }\n\n    // Save the file\n    dst := filepath.Join(\"uploads\", upload.File.Filename)\n    if err := c.SaveUploadedFile(upload.File, dst); err != nil {\n        c.JSON(500, map[string]string{\"error\": err.Error()})\n        return\n    }\n\n    c.JSON(201, map[string]string{\"message\": \"File uploaded successfully\"})\n},\ndocs.WithSummary(\"Upload file\"),\ndocs.WithMultipartFormStruct[FileUpload](\"File upload with metadata\"),\ndocs.WithJSONResponse[map[string]string](201, \"Upload successful\"),\n)\n```\n\n### Server-Sent Events\n\n```go\nr.GET(\"/events\", func(c *router.Context) {\n    c.InitSSE()\n    \n    // Send events\n    for i := 0; i \u003c 10; i++ {\n        err := c.SSE(router.SSEEvent{\n            Event: \"message\",\n            Data:  fmt.Sprintf(\"Event %d\", i),\n            ID:    fmt.Sprintf(\"msg-%d\", i),\n        })\n        if err != nil {\n            break\n        }\n        time.Sleep(time.Second)\n    }\n})\n```\n\n### Custom Type Handlers\n\n```go\nimport (\n    \"reflect\"\n    \"github.com/joakimcarlsson/go-router/metadata\"\n)\n\ntype UserID string\n\n// Register custom schema for OpenAPI documentation\nmetadata.RegisterTypeHandler(\"main.UserID\", func(t reflect.Type) metadata.Schema {\n    return metadata.Schema{\n        Type:    \"string\",\n        Format:  \"uuid\",\n        Example: \"550e8400-e29b-41d4-a716-446655440000\",\n    }\n})\n\ntype User struct {\n    ID   UserID `json:\"id\"`\n    Name string `json:\"name\"`\n}\n```\n\n### Authentication \u0026 Security\n\n```go\n// Setup OAuth2 security scheme\ngenerator := openapi.NewGenerator(openapi.Info{\n    Title:   \"Secure API\",\n    Version: \"1.0.0\",\n})\n\ngenerator.WithOAuth2ImplicitFlow(\"oauth2\", \"OAuth2 authentication\",\n    \"https://auth.example.com/oauth/authorize\",\n    map[string]string{\n        \"read\":  \"Read access\",\n        \"write\": \"Write access\",\n    },\n)\n\n// Add security to routes\nr.GET(\"/protected\", protectedHandler,\n    docs.WithSummary(\"Protected resource\"),\n    docs.WithOAuth2Scopes(\"read\"),\n    docs.WithBearerAuth(),\n)\n```\n\n## Performance\n\nGo Router is designed for high performance:\n\n- **Zero allocations** in hot routing paths\n- **Object pooling** for contexts and encoders\n- **Efficient path matching** using Go 1.22+ patterns\n- **Minimal middleware overhead**\n- **Concurrent request handling**\n\n### Benchmarks\n\nRun benchmarks to see performance characteristics:\n\n```bash\n# Core router benchmarks\ncd benchmarks \u0026\u0026 go test -bench=BenchmarkRouter_ -benchmem\n\n# Comparison with standard library\ncd benchmarks \u0026\u0026 go test -bench=BenchmarkComparison_ -benchmem\n\n# Memory allocation tests\ncd benchmarks \u0026\u0026 go test -bench=BenchmarkRouter_MemoryAllocation -benchmem\n```\n\nTypical results show excellent performance compared to standard library while providing significantly more features.\n\n## Migration Guides\n\n### From Gin\n\n```go\n// Gin\ngin.GET(\"/users/:id\", func(c *gin.Context) {\n    id := c.Param(\"id\")\n    c.JSON(200, gin.H{\"id\": id})\n})\n\n// Go Router\nr.GET(\"/users/{id}\", func(c *router.Context) {\n    id := c.Param(\"id\")\n    c.JSON(200, map[string]string{\"id\": id})\n})\n```\n\n### From Echo\n\n```go\n// Echo\ne.GET(\"/users/:id\", func(c echo.Context) error {\n    id := c.Param(\"id\")\n    return c.JSON(200, map[string]string{\"id\": id})\n})\n\n// Go Router\nr.GET(\"/users/{id}\", func(c *router.Context) {\n    id := c.Param(\"id\")\n    c.JSON(200, map[string]string{\"id\": id})\n})\n```\n\n### From Chi\n\n```go\n// Chi\nr.Get(\"/users/{id}\", func(w http.ResponseWriter, r *http.Request) {\n    id := chi.URLParam(r, \"id\")\n    json.NewEncoder(w).Encode(map[string]string{\"id\": id})\n})\n\n// Go Router\nr.GET(\"/users/{id}\", func(c *router.Context) {\n    id := c.Param(\"id\")\n    c.JSON(200, map[string]string{\"id\": id})\n})\n```\n\n## API Reference\n\n### Router Methods\n\n- `New()` - Create new router\n- `GET/POST/PUT/DELETE/PATCH(path, handler, ...options)` - Register routes\n- `Group(prefix, func)` - Create route groups\n- `Use(middleware...)` - Add middleware\n- `Run(addr)` - Start HTTP server\n- `ServeHTTP(w, r)` - Implement http.Handler\n\n### Context Methods\n\n- `Param(key)` - Get path parameter\n- `Query()` - Get query parameters\n- `JSON/XML/String(code, obj)` - Send responses\n- `BindJSON/BindXML/BindForm(obj)` - Parse request body\n- `Status(code)` - Set status code\n- `SetHeader/GetHeader(key, value)` - Manage headers\n- `File(path)` - Serve files\n- `Redirect(code, url)` - HTTP redirects\n\n### Documentation Options\n\n- `docs.WithSummary/WithDescription` - Basic documentation\n- `docs.WithTags` - Group operations\n- `docs.WithPathParam/WithQueryParam` - Document parameters\n- `docs.WithJSONRequest/Response[T]` - Type-safe schemas\n- `docs.WithSecurity/WithAuth` - Authentication requirements\n\n## Examples Directory\n\nExplore the `_examples` directory for complete, runnable examples:\n\n- **minimal-api** - Basic routing without documentation\n- **basic-api-with-docs** - Full OpenAPI integration\n- **file-upload** - Multipart form handling\n- **cors** - Cross-origin resource sharing\n- **oauth2-*** - Various OAuth2 flows\n- **server-sent-events** - Real-time event streaming\n- **custom-type-handlers** - Custom OpenAPI schemas\n\n## Design Goals\n\n1. **Modularity**: Use only the components you need\n2. **Type Safety**: Leverage Go's type system for documentation\n5. **Developer Experience**: Intuitive APIs with comprehensive examples\n6. **Extensibility**: Easy to add custom functionality\n\n## Contributing\n\nWe welcome contributions! Please see:\n\n- **Issues**: Report bugs or request features\n- **Pull Requests**: Submit improvements\n- **Documentation**: Help improve examples and guides\n- **Testing**: Add test cases or benchmarks\n\n### Development\n\n```bash\n# Run tests\ngo test ./...\n\n# Run benchmarks\ncd benchmarks \u0026\u0026 go test -bench=. -benchmem\n\n# Run linter\ngolangci-lint run\n\n# Check all examples\nfind _examples -name \"*.go\" -exec go run {} \\;\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details\n\n## Support\n\n- **Documentation**: [pkg.go.dev](https://pkg.go.dev/github.com/JoakimCarlsson/go-router)\n- **Examples**: See `_examples/` directory\n- **Issues**: [GitHub Issues](https://github.com/JoakimCarlsson/go-router/issues)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoakimcarlsson%2Fgo-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoakimcarlsson%2Fgo-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoakimcarlsson%2Fgo-router/lists"}