{"id":24845921,"url":"https://github.com/bndrmrtn/zex","last_synced_at":"2026-07-13T20:31:45.848Z","repository":{"id":272299157,"uuid":"915986813","full_name":"bndrmrtn/zex","owner":"bndrmrtn","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-06T14:54:49.000Z","size":25,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-06T10:05:34.146Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/bndrmrtn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-13T08:37:06.000Z","updated_at":"2025-06-26T16:32:35.000Z","dependencies_parsed_at":"2025-01-13T15:29:41.701Z","dependency_job_id":"bc2cb1b7-99db-4225-bb32-7df310e4c931","html_url":"https://github.com/bndrmrtn/zex","commit_stats":null,"previous_names":["bndrmrtn/zex"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/bndrmrtn/zex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bndrmrtn%2Fzex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bndrmrtn%2Fzex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bndrmrtn%2Fzex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bndrmrtn%2Fzex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bndrmrtn","download_url":"https://codeload.github.com/bndrmrtn/zex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bndrmrtn%2Fzex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35436278,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"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":[],"created_at":"2025-01-31T10:17:18.140Z","updated_at":"2026-07-13T20:31:45.823Z","avatar_url":"https://github.com/bndrmrtn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zex (/ziː.ɛks/)\n\nAn easy-to-use http router for Go.\n\n## Installation\n\nCreate a new go project and install the package with the following command:\n\n```\ngo get github.com/bndrmrtn/zex@latest\n```\n\n## Usage\n\n```go\napp := zex.New() // with default configuration\napp := zex.New(\u0026zex.Config{\n\tDevelopment: true,\n\tNotFoundHandler: http.NotFound,\n}) // with custom configuration\n```\n\n## Routing\n\nZex provides a straightforward way to define and manage HTTP routing. Routing allows you to define specific paths and associate them with handler functions that process incoming HTTP requests. Zex supports dynamic routes, where parts of the path are treated as variables, allowing you to easily capture parameters from the URL.\n\n### Defining Routes\n\nWith Zex, you can define routes using methods like `Get()`, `Post()`, and other HTTP method handlers. Each route is associated with a URL pattern, and when a request matches this pattern, the corresponding handler function is executed.\n\n```go\n// simple http get request\napp.Get(\"/hello\", func(w http.ResponseWriter, r *http.Request) {\n\tw.Write([]byte(\"Hello, world!\"))\n})\n```\n\nIn this example, any `GET` request to the `/hello` path will invoke the handler that responds with `\"Hello, world!\"`.\n\n### Dynamic Routes\n\nZex allows you to define dynamic routes that can capture variables from the URL path. These variables are then accessible in your handler function.\n\n```go\napp.Get(\"/user/{id}\", func(w http.ResponseWriter, r *http.Request) {\n\tuserID := zx.Param(r, \"id\")\n\tw.Write([]byte(\"User ID is \" + userID))\n})\n```\n\nIn this example, the `{id}` part of the URL is a placeholder that will match any string. When a request like `/user/123` is made, the value `123` will be captured as a parameter and can be accessed using `zx.Param(r, \"id\")`.\n\n```go\napp.Get(\"/optional/{id}?\", func(...) {...})\n```\nOptional parameters are also supported via `?` mark.\nIn this case, both `/optional` and `/optional/any` will work.\n\n### Route Parameter Validation\n\nZex also supports route parameter validation with the `@` symbol.\nA route should look like this:\n```go\napp.Get(\"/optional/{id@uuid}\", func(...) {...})\n```\n\nIn this example, the `id` parameter is validated, and if it’s not a valid `UUIDv4`, the default NotFound error handler is triggered.\n\nZex also lets you define custom route parameter validators.\n\n```go\napp.RegisterParamValidator(\"png\", func(value string) (string, error) {\n\tstrs := strings.SplitN(value, \".\", 2)\n\tif strs[len(strs)-1] != \"png\" {\n\t\treturn \"\", errors.New(\"file extension is not png\")\n\t}\n\n\treturn strs[0], nil\n})\n```\n\n## Error Handling\n\n### Handlers With Error Return\n\nZex provides a flexible error-handling system.\nUse `HandlerFuncWithErr` to write handlers that return errors, and wrap them with `NewWithErrorConverter` to ensure consistent error handling.\nBy default, `DefaultErrHandler` logs errors and sends appropriate HTTP responses, but you can define custom handlers to suit your needs.\n\n```go\ne := zex.NewWithErrorConverter()\n\napp.Get(\"/error\", e(func(w http.ResponseWriter, r *http.Request) error {\n\treturn zex.NewError(400, \"Bad request\").SetInternal(errors.New(\"internal error\"))\n}))\n```\n\nInternal errors can be used to provide additional context to the error message.\nThey are not sent to the client but are logged for debugging purposes.\nThere are also built-in error types like `ErrNotFoun`, `ErrBadRequest`, etc.\n\n### Built-in Error Type\n\nZex includes a customizable error type, `Error`, to simplify error management:\n- Fields: Stores HTTP status, error message, and an optional internal error for debugging.\n- Methods:\n  - `Error()`: Returns the error message.\n  - `Status()`: Returns the HTTP status code.\n  - `SetInternal(err)`: Sets an internal error for additional context.\n  - `Internal()`: Retrieves the internal error.\n\nPredefined errors like `ErrBadRequest` help standardize client-side error responses.\nUse `NewError` to create additional custom errors as needed.\n\n## Built-in Utilities\n\nZex comes with `zx`, a handy utility library to make repetitive tasks faster and easier. (currently in development)\n\n```go\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t// get url param\n\tid := zx.Param(r, \"id\")\n\t// get url param as int\n\tnum, err := zx.ParamInt(r, \"num\")\n\t// get query parameter\n\tquery := zx.Query(r, \"key\")\n\t// bind body\n\terr := zx.Bind(r, \u0026struct{}{})\n\t// get header\n\theader := zx.Header(r, \"key\")\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbndrmrtn%2Fzex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbndrmrtn%2Fzex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbndrmrtn%2Fzex/lists"}