{"id":47753274,"url":"https://github.com/xraph/steel","last_synced_at":"2026-04-03T03:52:05.668Z","repository":{"id":303510394,"uuid":"1015737150","full_name":"xraph/steel","owner":"xraph","description":"Not just yet another Go Lang Router","archived":false,"fork":false,"pushed_at":"2025-07-10T21:03:16.000Z","size":1572,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-11T10:53:48.105Z","etag":null,"topics":["go"],"latest_commit_sha":null,"homepage":"https://steel.xraph.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xraph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":"juicycleff","custom":["https://steel.xraph.com","https://xraph.com"]}},"created_at":"2025-07-08T01:05:21.000Z","updated_at":"2025-07-10T20:50:59.000Z","dependencies_parsed_at":"2025-07-11T11:08:01.579Z","dependency_job_id":null,"html_url":"https://github.com/xraph/steel","commit_stats":null,"previous_names":["xraph/forgerouter","xraph/steel"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/xraph/steel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xraph%2Fsteel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xraph%2Fsteel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xraph%2Fsteel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xraph%2Fsteel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xraph","download_url":"https://codeload.github.com/xraph/steel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xraph%2Fsteel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31332835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T03:20:36.090Z","status":"ssl_error","status_checked_at":"2026-04-03T03:20:35.133Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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"],"created_at":"2026-04-03T03:52:02.714Z","updated_at":"2026-04-03T03:52:05.657Z","avatar_url":"https://github.com/xraph.png","language":"Go","funding_links":["https://github.com/sponsors/juicycleff","https://steel.xraph.com","https://xraph.com"],"categories":[],"sub_categories":[],"readme":"# Steel Router 🚀\n\nA high-performance HTTP router for Go with automatic OpenAPI documentation, WebSocket/SSE support, and comprehensive testing utilities.\n\n[![Go Version](https://img.shields.io/badge/go-1.24+-blue.svg)](https://golang.org)\n[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/xraph/steel)](https://goreportcard.com/report/github.com/xraph/steel)\n\n## ✨ Features\n\n- **🚀 High Performance**: Fast radix tree-based routing with zero allocations for parameter extraction\n- **📚 Automatic OpenAPI**: Generate complete OpenAPI 3.0 documentation from your handlers\n- **🔌 Real-time**: Built-in WebSocket and Server-Sent Events (SSE) support with AsyncAPI docs\n- **🎯 Type-Safe**: Opinionated handlers with automatic parameter binding and validation\n- **🧪 Testing**: Comprehensive testing utilities with request builders and assertions\n- **⚡ Middleware**: Flexible middleware system with built-in recovery, logging, and timeout\n- **🎨 Multiple Docs**: Support for Swagger UI, ReDoc, Scalar, and Stoplight Elements\n- **🔧 Developer-Friendly**: Rich debugging tools and development utilities\n\n## 📦 Installation\n\n```bash\ngo get github.com/xraph/steel\n```\n\n## 🚀 Quick Start\n\n```go\npackage main\n\nimport (\n    \"log\"\n    \"net/http\"\n    \n\t\"github.com/xraph/steel\"\n)\n\ntype User struct {\n    ID   int    `json:\"id\" path:\"id\" description:\"User ID\"`\n    Name string `json:\"name\" query:\"name\" description:\"User name\"`\n}\n\ntype UserResponse struct {\n    ID      int    `json:\"id\" description:\"User ID\"`\n    Name    string `json:\"name\" description:\"User name\"`\n    Created bool   `json:\"created\" description:\"Whether user was created\"`\n}\n\nfunc main() {\n    r := steel.NewRouter()\n    \n    // Add middleware\n    r.Use(steel.Logger, steel.Recoverer)\n    \n    // Opinionated handler with automatic OpenAPI generation\n    r.OpinionatedGET(\"/users/:id\", func(ctx *steel.Context, req User) (*UserResponse, error) {\n        return \u0026UserResponse{\n            ID:      req.ID,\n            Name:    req.Name,\n            Created: false,\n        }, nil\n    }, steel.WithSummary(\"Get User\"), steel.WithTags(\"users\"))\n    \n    // Enable automatic OpenAPI documentation\n    r.EnableOpenAPI()\n    \n    log.Println(\"Server starting on :8080\")\n    log.Println(\"API docs available at http://localhost:8080/openapi/docs\")\n    log.Fatal(http.ListenAndServe(\":8080\", r))\n}\n```\n\nVisit `http://localhost:8080/openapi/docs` to see your automatically generated API documentation!\n\n## 🎯 Key Features\n\n### Opinionated Handlers\n\nSteel's opinionated handlers provide automatic parameter binding, validation, and OpenAPI generation:\n\n```go\ntype CreateUserRequest struct {\n    Name  string `json:\"name\" body:\"body\" description:\"User name\"`\n    Email string `json:\"email\" body:\"body\" description:\"User email\"`\n    Age   int    `query:\"age\" description:\"User age\"`\n}\n\nr.OpinionatedPOST(\"/users\", func(ctx *router.Context, req CreateUserRequest) (*UserResponse, error) {\n    // Request automatically bound from JSON body and query parameters\n    if req.Age \u003c 18 {\n        return nil, router.BadRequest(\"User must be 18 or older\")\n    }\n    \n    // Your business logic here\n    return \u0026UserResponse{ID: 123, Name: req.Name}, nil\n}, router.WithSummary(\"Create User\"))\n```\n\n### Real-time Communication\n\nBuilt-in WebSocket and SSE support with AsyncAPI documentation:\n\n```go\n// WebSocket handler\nr.WebSocket(\"/ws/chat\", func(conn *router.WSConnection, message ChatMessage) (*ChatResponse, error) {\n    return \u0026ChatResponse{Reply: \"Echo: \" + message.Text}, nil\n}, router.WithAsyncSummary(\"Chat WebSocket\"))\n\n// Server-Sent Events\nr.SSE(\"/events/:userId\", func(conn *router.SSEConnection, params EventParams) error {\n    return conn.SendMessage(router.SSEMessage{\n        Event: \"notification\",\n        Data:  map[string]interface{}{\"userId\": params.UserID},\n    })\n}, router.WithAsyncSummary(\"User Events\"))\n\n// Enable AsyncAPI documentation\nr.EnableAsyncAPI()\n```\n\n### Comprehensive Error Handling\n\nRich error types with automatic OpenAPI documentation:\n\n```go\nr.OpinionatedGET(\"/users/:id\", func(ctx *router.Context, req GetUserRequest) (*User, error) {\n    user, exists := database.GetUser(req.ID)\n    if !exists {\n        return nil, router.NotFound(\"User\")\n    }\n    \n    if !user.Active {\n        return nil, router.Forbidden(\"User account is deactivated\")\n    }\n    \n    return user, nil\n})\n```\n\n### Testing Made Easy\n\nBuilt-in testing utilities for comprehensive API testing:\n\n```go\nfunc TestUserAPI(t *testing.T) {\n    router := setupTestRouter()\n    \n    // Test user creation\n    response := router.NewRequest(\"POST\", \"/users\").\n        WithJSON(map[string]interface{}{\n            \"name\": \"John Doe\",\n            \"email\": \"john@example.com\",\n        }).\n        Execute(router)\n    \n    router.AssertResponse(t, response).\n        Status(http.StatusCreated).\n        IsJSON().\n        JSON(\"name\", \"John Doe\")\n}\n```\n\n## 📖 Documentation\n\n### Basic Routing\n\n```go\nr := router.NewRouter()\n\n// HTTP methods\nr.GET(\"/\", handler)\nr.POST(\"/users\", handler)\nr.PUT(\"/users/:id\", handler)\nr.DELETE(\"/users/:id\", handler)\n\n// Path parameters\nr.GET(\"/users/:id/posts/:postId\", handler)\n\n// Wildcards\nr.GET(\"/static/*\", handler)\n\n// Route groups\nr.Route(\"/api/v1\", func(r router.Router) {\n    r.GET(\"/users\", getUsersHandler)\n    r.POST(\"/users\", createUserHandler)\n})\n```\n\n### Middleware\n\n```go\n// Built-in middleware\nr.Use(router.Logger)\nr.Use(router.Recoverer)\nr.Use(router.Timeout(30 * time.Second))\n\n// Custom middleware\nr.Use(func(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {\n        // Your middleware logic\n        next.ServeHTTP(w, req)\n    })\n})\n```\n\n### Parameter Binding Tags\n\n| Tag | Description | Example |\n|-----|-------------|---------|\n| `path` | URL path parameter | `ID int \\`path:\"id\"\\`` |\n| `query` | Query parameter | `Limit int \\`query:\"limit\"\\`` |\n| `header` | HTTP header | `Auth string \\`header:\"Authorization\"\\`` |\n| `body` | JSON body field | `Data string \\`body:\"body\"\\`` |\n| `json` | JSON field name | `Name string \\`json:\"name\"\\`` |\n| `description` | OpenAPI description | `ID int \\`description:\"User ID\"\\`` |\n\n## 🔧 Advanced Features\n\n### Custom Response Types\n\n```go\nr.OpinionatedPOST(\"/users\", func(ctx *router.Context, req CreateUserRequest) (*router.APIResponse, error) {\n    user := createUser(req)\n    \n    return router.Created(user).\n        WithHeader(\"Location\", fmt.Sprintf(\"/users/%d\", user.ID)), nil\n})\n```\n\n### Validation Errors\n\n```go\nfunc validateUser(req CreateUserRequest) error {\n    fields := []router.FieldError{}\n    \n    if req.Email == \"\" {\n        fields = append(fields, router.NewFieldError(\"email\", \"Email is required\", req.Email, \"REQUIRED\"))\n    }\n    \n    if len(fields) \u003e 0 {\n        return router.UnprocessableEntity(\"Validation failed\", fields...)\n    }\n    \n    return nil\n}\n```\n\n### Connection Management\n\n```go\n// Get connection manager for WebSocket/SSE connections\ncm := router.ConnectionManager()\n\n// Broadcast to all WebSocket connections\ncm.BroadcastWS(router.WSMessage{\n    Type:    \"notification\",\n    Payload: \"Hello everyone!\",\n})\n\n// Broadcast to all SSE connections\ncm.BroadcastSSE(router.SSEMessage{\n    Event: \"update\",\n    Data:  \"System maintenance in 5 minutes\",\n})\n```\n\n## 📊 Documentation Viewers\n\nSteel supports multiple documentation viewers out of the box:\n\n- **Swagger UI**: Interactive API documentation\n- **ReDoc**: Beautiful, responsive documentation\n- **Scalar**: Modern documentation with excellent UX\n- **Stoplight Elements**: Comprehensive documentation platform\n\nAccess them at:\n- `/openapi/docs` - Documentation hub\n- `/openapi/swagger` - Swagger UI\n- `/openapi/redoc` - ReDoc\n- `/openapi/scalar` - Scalar\n- `/openapi/spotlight` - Stoplight Elements\n- `/asyncapi/docs` - AsyncAPI documentation\n\n## 🧪 Testing\n\n### Load Testing\n\n```go\nconfig := router.LoadTestConfig{\n    Concurrency: 10,\n    Requests:    1000,\n    Timeout:     30 * time.Second,\n    Paths:       []string{\"/api/users\", \"/api/posts\"},\n}\n\nresult := router.RunLoadTest(router, config)\nfmt.Printf(\"RPS: %.2f, Success: %d%%\\n\", \n    result.RequestsPerSecond, \n    (result.SuccessRequests*100)/result.TotalRequests)\n```\n\n### Benchmark Testing\n\n```go\nfunc BenchmarkUserAPI(b *testing.B) {\n    setup := router.NewBenchmarkSetup().\n        AddStaticRoutes(100).\n        AddParameterRoutes(50)\n    \n    router := setup.Setup()\n    \n    b.ResetTimer()\n    for i := 0; i \u003c b.N; i++ {\n        // Your benchmark code\n    }\n}\n```\n\n## 🔗 Integration Examples\n\n### With Database (GORM)\n\n```go\ntype UserService struct {\n    db *gorm.DB\n}\n\nfunc (s *UserService) GetUser(ctx *router.Context, req GetUserRequest) (*User, error) {\n    var user User\n    if err := s.db.First(\u0026user, req.ID).Error; err != nil {\n        if errors.Is(err, gorm.ErrRecordNotFound) {\n            return nil, router.NotFound(\"User\")\n        }\n        return nil, router.InternalServerError(\"Database error\")\n    }\n    return \u0026user, nil\n}\n\n// Register handler\nr.OpinionatedGET(\"/users/:id\", userService.GetUser)\n```\n\n### With Validation (go-playground/validator)\n\n```go\ntype CreateUserRequest struct {\n    Name  string `json:\"name\" validate:\"required,min=2\" description:\"User name\"`\n    Email string `json:\"email\" validate:\"required,email\" description:\"User email\"`\n    Age   int    `json:\"age\" validate:\"min=18\" description:\"User age\"`\n}\n\nfunc createUserWithValidation(ctx *router.Context, req CreateUserRequest) (*User, error) {\n    if err := validator.New().Struct(req); err != nil {\n        var fields []router.FieldError\n        for _, err := range err.(validator.ValidationErrors) {\n            fields = append(fields, router.NewFieldError(\n                err.Field(), \n                err.Error(), \n                err.Value(), \n                err.Tag(),\n            ))\n        }\n        return nil, router.UnprocessableEntity(\"Validation failed\", fields...)\n    }\n    \n    // Create user...\n    return \u0026User{}, nil\n}\n```\n\n## 🏗️ Architecture\n\nSteel is built with performance and developer experience in mind:\n\n- **Radix Tree Routing**: Efficient O(log n) route matching\n- **Zero Allocations**: Parameter extraction without memory allocations\n- **Reflection-Based Binding**: Automatic request binding using Go reflection\n- **OpenAPI Generation**: Real-time schema generation from Go types\n- **Connection Pooling**: Efficient parameter object pooling\n- **Middleware Chain**: Flexible middleware composition\n- **Error Handling**: Structured error responses with automatic documentation\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Inspired by [Chi](https://github.com/go-chi/chi) and [Gin](https://github.com/gin-gonic/gin)\n- OpenAPI 3.0 specification\n- AsyncAPI 2.6 specification\n- Go community for amazing ecosystem\n\n## 📞 Support\n\n- 📖 [Documentation](https://steel.xraph.com)\n- 🐛 [Report Bug](https://github.com/xraph/steel/issues)\n- 💡 [Request Feature](https://github.com/xraph/steel/issues)\n- 💬 [Discussions](https://github.com/xraph/steel/discussions)\n\n---\n\n**Made with ❤️ by the XRaph team**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxraph%2Fsteel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxraph%2Fsteel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxraph%2Fsteel/lists"}