{"id":26685467,"url":"https://github.com/gyozatech/temaki","last_synced_at":"2026-02-17T05:02:39.577Z","repository":{"id":153797264,"uuid":"422265853","full_name":"gyozatech/temaki","owner":"gyozatech","description":"Minimal HTTP router based on the net/http standard library","archived":false,"fork":false,"pushed_at":"2025-04-07T16:41:18.000Z","size":143,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-12T15:59:47.437Z","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":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gyozatech.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}},"created_at":"2021-10-28T15:53:46.000Z","updated_at":"2025-04-07T16:40:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"07a74b94-7b40-42e6-a740-86d387ed05b4","html_url":"https://github.com/gyozatech/temaki","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/gyozatech/temaki","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyozatech%2Ftemaki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyozatech%2Ftemaki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyozatech%2Ftemaki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyozatech%2Ftemaki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyozatech","download_url":"https://codeload.github.com/gyozatech/temaki/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyozatech%2Ftemaki/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29534471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T05:00:25.817Z","status":"ssl_error","status_checked_at":"2026-02-17T04:57:16.126Z","response_time":100,"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":[],"created_at":"2025-03-26T10:16:19.938Z","updated_at":"2026-02-17T05:02:39.560Z","avatar_url":"https://github.com/gyozatech.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# temaki\n\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) \n[![made-with-Go](https://img.shields.io/badge/Made%20with-Go-1f425f.svg)](http://golang.org)\n[![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/)\n\n![alt text](assets/logo.png?raw=true)\n\nMinimal HTTP router based on the net/http standard library.\n\n## Usage\n\nCreating a _router_ object with **temaki** is very simple:\n\n```golang\npackage main\n\nimport (\n    \"github.com/gyozatech/temaki\"\n    \"github.com/gyozatech/temaki/middlewares\"\n    \"log\"\n    \"net/http\"\n    \"fmt\"\n    \"strconv\"\n)\n\nvar logger *log.Logger\n\nfunc init() {\n\tlogger = log.New(os.Stdout, \"\", log.LstdFlags)\n}\n\nfunc main() {\n    router := temaki.NewRouter()\n\n    // passing a custom logger to the middlewares (the default is gyozatch/noodlog)\n    middlewares.SetLogger(logger)\n    \n    // provided temaki middlewares\n    router.UseMiddleware(middlewares.RecoverPanicMiddleware)\n    router.UseMiddleware(middlewares.RequestLoggerMiddleware)\n    router.UseMiddleware(middlewares.CORSMiddleware)\n    // custom middleware\n    router.UseMiddleware(authMiddleware)\n\n    // routes\n    router.GET(\"/api/v1/stores/{storeId}/products/{productId}\", getProductHandler)\n    router.POST(\"/api/v1/stores/{storeId([^/]+)}/products/{productId([0-9]+)}\", addProductHandler)\n    router.PATCH(\"/api/v1/stores/{storeId([^/]+)}/products/{productId}\", updateProductHandler)\n    router.DELETE(\"/api/v1/stores/{storeId}/products/{productId([0-9]+)}\", deleteProductHandler)\n\n    log.Fatal(router.Start(8080))\n}\n\n// MIDDLEWARE\nfunc authMiddleware(handler http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Println(\"Executing middleware before request phase!\")\n\t\ttoken, err := temaki.GetBearerToken(r)\n\t\tif err != nil {\n\t\t\tlogger.Error(err)\n\t\t\thttp.Error(w, err.Error(), http.StatusUnauthorized)\n\t\t\treturn\n\t\t}\n\t\tif token != \"IcgFd3FiHwKDM2H\" {\n            http.Error(w, \"invalid bearer token provided\", http.StatusUnauthorized)\n\t\t\treturn\n\t\t}\n\t\thandler.ServeHTTP(w, r)\n\t\tfmt.Println(\"Executing middleware after request phase!\")\n\t})\n}\n\n// HANDLERS ********\n\nfunc getProductHandler(w http.ResponseWriter, r *http.Request) {\n\tstoreId := temaki.GetPathParam(r, \"storeId\")\n\tproductId, _ := strconv.Atoi(temaki.GetPathParam(r, \"productId\"))\n\tfmt.Fprintf(w, \"getProductHandler %s %d\\n\", storeId, productId)\n}\n\nfunc addProductHandler(w http.ResponseWriter, r *http.Request) {\n\tstoreId := temaki.GetPathParam(r, \"storeId\")\n\tproductId, _ := strconv.Atoi(temaki.GetPathParam(r, \"productId\"))\n\tfmt.Fprintf(w, \"addProductHandler %s %d\\n\", storeId, productId)\n}\n\nfunc updateProductHandler(w http.ResponseWriter, r *http.Request) {\n\tstoreId := temaki.GetPathParam(r, \"storeId\")\n\tproductId, _ := strconv.Atoi(temaki.GetPathParam(r, \"productId\"))\n\tfmt.Fprintf(w, \"updateProductHandler %s %d\\n\", storeId, productId)\n}\n\nfunc deleteProductHandler(w http.ResponseWriter, r *http.Request) {\n\tstoreId := temaki.GetPathParam(r, \"storeId\")\n\tproductId, _ := strconv.Atoi(temaki.GetPathParam(r, \"productId\"))\n\tfmt.Fprintf(w, \"deleteProductHandler %s %d\\n\", storeId, productId)\n}\n\n```\n\nAs you have noticed from the _paths_ you can also decide to specify a **regex** pattern to the path parameters.\n\n## Contributing\n\nAny contribution to this project is welcome! Just fork the project, and open a Pull Request.\n\nIf you find a problem or a bug, or have some improvement suggestion, please open an issue or a discussion on Github.\n\n## Special thanks\n\nThanks to [benhoyt](https://github.com/benhoyt/go-routing) who gaves me the idea for this wrapper.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyozatech%2Ftemaki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyozatech%2Ftemaki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyozatech%2Ftemaki/lists"}