{"id":13752261,"url":"https://github.com/go-fuego/fuego","last_synced_at":"2025-05-14T12:12:46.131Z","repository":{"id":200990846,"uuid":"706256859","full_name":"go-fuego/fuego","owner":"go-fuego","description":"Golang Fuego - Web framework generating OpenAPI 3 spec from source code - Pluggable to existing Gin \u0026 Echo APIs","archived":false,"fork":false,"pushed_at":"2025-05-13T12:17:50.000Z","size":11630,"stargazers_count":1360,"open_issues_count":31,"forks_count":106,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-14T09:56:04.701Z","etag":null,"topics":["echo","fuego","gin-gonic","golang","http-server","openapi"],"latest_commit_sha":null,"homepage":"https://go-fuego.dev/","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/go-fuego.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["EwenQuim"]}},"created_at":"2023-10-17T15:36:43.000Z","updated_at":"2025-05-14T04:59:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"98db0671-927c-4223-891f-3b7338fa5c9d","html_url":"https://github.com/go-fuego/fuego","commit_stats":{"total_commits":636,"total_committers":32,"mean_commits":19.875,"dds":0.3207547169811321,"last_synced_commit":"7dd81256184cc44241388db6a69464f15145df4c"},"previous_names":["go-op/op","go-fuego/fuego"],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-fuego%2Ffuego","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-fuego%2Ffuego/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-fuego%2Ffuego/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-fuego%2Ffuego/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-fuego","download_url":"https://codeload.github.com/go-fuego/fuego/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140768,"owners_count":22021220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["echo","fuego","gin-gonic","golang","http-server","openapi"],"created_at":"2024-08-03T09:01:02.577Z","updated_at":"2025-05-14T12:12:46.040Z","avatar_url":"https://github.com/go-fuego.png","language":"Go","funding_links":["https://github.com/sponsors/EwenQuim"],"categories":["Web Frameworks","Go","TODO:","\u003ca name=\"Go\"\u003e\u003c/a\u003eGo","Web框架"],"sub_categories":["Utility/Miscellaneous","实用程序/Miscellaneous"],"readme":"\u003c!-- markdownlint-disable MD041 --\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./static/fuego.svg\" height=\"200\" alt=\"Fuego Logo\" /\u003e\n\u003c/p\u003e\n\n# Fuego 🔥\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-fuego/fuego.svg)](https://pkg.go.dev/github.com/go-fuego/fuego)\n[![Go Report Card](https://goreportcard.com/badge/github.com/go-fuego/fuego)](https://goreportcard.com/report/github.com/go-fuego/fuego)\n[![Coverage Status](https://coveralls.io/repos/github/go-fuego/fuego/badge.svg?branch=main)](https://coveralls.io/github/go-fuego/fuego?branch=main)\n[![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23fuego-%237289da?)](https://discord.gg/9csuB6WNsq)\n\n\u003e The framework for busy Go developers\n\n🚀 **Explore and contribute to our [2025 Roadmap](https://github.com/go-fuego/fuego/discussions/263)!** 🚀\n\nProduction-ready Go API framework generating OpenAPI documentation from code.\nInspired by Nest, built for Go developers.\n\nAlso empowers templating with `html/template`, `a-h/templ` and `maragudk/gomponents`:\nsee [the example](./examples/full-app-gourmet) [running live](https://gourmet.quimerch.com).\n\n## Sponsors\n\nFuego is proudly sponsored by [Zuplo](https://zuplo.link/fuego-gh),\nthat provides [a Fuego integration](https://zuplo.link/fuego-gh)!\n\n\u003cdiv align=\"center\"\u003e\n\t\u003cimg src=\"./assets/Zuplo.png\" style=\"border-radius:10px\" height=\"100\"\n\talt=\"Fuego Logo\" /\u003e\n\u003c/div\u003e\n\n\u003e Zuplo allows you to secure your Fuego API, scale it globally,\n\u003e generate documentation from your OpenAPI, and monetize your users.\n\n## Why Fuego?\n\nChi, Gin, Fiber and Echo are great frameworks.\nBut since they were designed a long time ago,\n[their current API does not allow them][gin-gonic-issue] to deduce\nOpenAPI types from signatures, things that are now possible with generics.\nFuego offers a lot of \"modern Go based\" features that make it easy\nto develop APIs and web applications.\n\n## Features\n\n- **OpenAPI**: Fuego automatically generates OpenAPI documentation\n  from **code** - _not from comments nor YAML files!_\n- **100% `net/http` compatible** (no lock-in): Fuego is built on top of `net/http`,\n  so you can use any `http.Handler` middleware or handler! Fuego also supports\n  `log/slog`, `context` and `html/template`.\n- **Routing**: Fuego router is based on Go 1.22 `net/http`, with grouping and\n  middleware support\n- **Serialization/Deserialization**: Fuego automatically serializes and\n  deserializes JSON, XML and HTML Forms based on user-provided structs\n  (or not, if you want to do it yourself)\n- **Validation**: Fuego provides a simple and fast validator based on `go-playground/validator`\n- **Transformation**: easily transform your data by implementing the\n  `fuego.InTransform` and `fuego.OutTransform` interfaces - also useful for\n  custom **validation**\n- **Middlewares**: easily add a custom `net/http` middleware\n  or use the provided middlewares.\n- **Error handling**: Fuego provides centralized error handling with\n  the standard [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457).\n- **Rendering**: Fuego provides a simple and fast rendering system based on\n  `html/template` - you can still also use your own template system like\n  `templ` or `gomponents`\n- **Adaptors**: Fuego can be plugged to an existing Gin or Echo server to\n  generate OpenAPI documentation\n\n## Examples\n\n### Hello World\n\n```go\npackage main\n\nimport \"github.com/go-fuego/fuego\"\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\tfuego.Get(s, \"/\", func(c fuego.ContextNoBody) (string, error) {\n\t\treturn \"Hello, World!\", nil\n\t})\n\n\ts.Run()\n}\n```\n\n### Simple POST\n\n```go\npackage main\n\nimport \"github.com/go-fuego/fuego\"\n\ntype MyInput struct {\n\tName string `json:\"name\" validate:\"required\"`\n}\n\ntype MyOutput struct {\n\tMessage string `json:\"message\"`\n}\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Automatically generates OpenAPI documentation for this route\n\tfuego.Post(s, \"/user/{user}\", myController)\n\n\ts.Run()\n}\n\nfunc myController(c fuego.ContextWithBody[MyInput]) (*MyOutput, error) {\n\tbody, err := c.Body()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn \u0026MyOutput{Message: \"Hello, \" + body.Name}, nil\n}\n```\n\n### With transformation \u0026 custom validation\n\n```go\ntype MyInput struct {\n\tName string `json:\"name\" validate:\"required\"`\n}\n\n// Will be called just before returning c.Body()\nfunc (r *MyInput) InTransform(context.Context) error {\n\tr.Name = strings.ToLower(r.Name)\n\n\tif r.Name == \"fuego\" {\n\t\treturn errors.New(\"fuego is not a valid name for this input\")\n\t}\n\n\treturn nil\n}\n```\n\n### More OpenAPI documentation\n\n```go\npackage main\n\nimport (\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/go-fuego/fuego/option\"\n\t\"github.com/go-fuego/fuego/param\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Custom OpenAPI options\n\tfuego.Post(s, \"/\", myController,\n\t\toption.Description(\"This route does something...\"),\n\t\toption.Summary(\"This is my summary\"),\n\t\toption.Tags(\"MyTag\"), // A tag is set by default according to the return type (can be deactivated)\n\t\toption.Deprecated(),  // Marks the route as deprecated in the OpenAPI spec\n\n\t\toption.Query(\"name\", \"Declares a query parameter with default value\", param.Default(\"Carmack\")),\n\t\toption.Header(\"Authorization\", \"Bearer token\", param.Required()),\n\t\toptionPagination,\n\t\toptionCustomBehavior,\n\t)\n\n\ts.Run()\n}\n\nvar optionPagination = option.Group(\n\toption.QueryInt(\"page\", \"Page number\", param.Default(1), param.Example(\"1st page\", 1), param.Example(\"42nd page\", 42)),\n\toption.QueryInt(\"perPage\", \"Number of items per page\"),\n)\n\nvar optionCustomBehavior = func(r *fuego.BaseRoute) {\n\tr.XXX = \"YYY\"\n}\n```\n\n### Std lib compatibility\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/go-fuego/fuego\"\n)\n\nfunc main() {\n\ts := fuego.NewServer()\n\n\t// Standard net/http middleware\n\tfuego.Use(s, func(next http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tw.Header().Set(\"X-Hello\", \"World\")\n\t\t\tnext.ServeHTTP(w, r)\n\t\t})\n\t})\n\n\t// Standard net/http handler with automatic OpenAPI route declaration\n\tfuego.GetStd(s, \"/std\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(\"Hello, World!\"))\n\t})\n\n\ts.Run()\n}\n```\n\n### Real-world examples\n\nPlease see the [`/examples` folder](./examples/) for more examples.\n\n- [Simple CRUD with OpenAPI](./examples/petstore)\n- [Full app with HTML rendering](./examples/full-app-gourmet)\n\n\u003cdetails\u003e\n\u003csummary\u003eAll features\u003c/summary\u003e\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n\n\tchiMiddleware \"github.com/go-chi/chi/v5/middleware\"\n\t\"github.com/go-fuego/fuego\"\n\t\"github.com/rs/cors\"\n)\n\ntype Received struct {\n\tName string `json:\"name\" validate:\"required\"`\n}\n\ntype MyResponse struct {\n\tMessage       string `json:\"message\"`\n\tBestFramework string `json:\"best\"`\n}\n\nfunc main() {\n\ts := fuego.NewServer(\n\t\tfuego.WithAddr(\"localhost:8088\"),\n\t)\n\n\tfuego.Use(s, cors.Default().Handler)\n\tfuego.Use(s, chiMiddleware.Compress(5, \"text/html\", \"text/css\"))\n\n\t// Fuego 🔥 handler with automatic OpenAPI generation, validation, (de)serialization and error handling\n\tfuego.Post(s, \"/\", func(c fuego.ContextWithBody[Received]) (MyResponse, error) {\n\t\tdata, err := c.Body()\n\t\tif err != nil {\n\t\t\treturn MyResponse{}, err\n\t\t}\n\n\t\tc.Response().Header().Set(\"X-Hello\", \"World\")\n\n\t\treturn MyResponse{\n\t\t\tMessage:       \"Hello, \" + data.Name,\n\t\t\tBestFramework: \"Fuego!\",\n\t\t}, nil\n\t})\n\n\t// Standard net/http handler with automatic OpenAPI route declaration\n\tfuego.GetStd(s, \"/std\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.Write([]byte(\"Hello, World!\"))\n\t})\n\n\ts.Run()\n}\n\n// InTransform will be called when using c.Body().\n// It can be used to transform the entity and raise custom errors\nfunc (r *Received) InTransform(context.Context) error {\n\tr.Name = strings.ToLower(r.Name)\n\tif r.Name == \"fuego\" {\n\t\treturn errors.New(\"fuego is not a name\")\n\t}\n\treturn nil\n}\n\n// OutTransform will be called before sending data\nfunc (r *MyResponse) OutTransform(context.Context) error {\n\tr.Message = strings.ToUpper(r.Message)\n\treturn nil\n}\n```\n\n```bash\ncurl http://localhost:8088/std\n# Hello, World!\ncurl http://localhost:8088 -X POST -d '{\"name\": \"Your Name\"}' -H 'Content-Type: application/json'\n# {\"message\":\"HELLO, YOUR NAME\",\"best\":\"Fuego!\"}\ncurl http://localhost:8088 -X POST -d '{\"name\": \"Fuego\"}' -H 'Content-Type: application/json'\n# {\"error\":\"cannot transform request body: cannot transform request body: fuego is not a name\"}\n```\n\n\u003c/details\u003e\n\n## From net/http to Fuego in 10s\n\n\u003chttps://github.com/go-fuego/fuego/assets/46993939/7438a71c-75a4-4e88-a584-71da6362c575\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eViews\u003c/summary\u003e\n\n### Before\n\n\u003cimg width=\"946\" alt=\"image\" src=\"https://github.com/go-fuego/fuego/assets/46993939/394fed17-a1e2-4b67-89b2-8e6c9eeb771b\"\u003e\n\n#### After\n\n\u003cimg width=\"1010\" alt=\"image\" src=\"https://github.com/go-fuego/fuego/assets/46993939/321088d7-bec4-46cc-a7ee-9a0fa45d7711\"\u003e\n\n#### Diff\n\n\u003cimg width=\"1413\" alt=\"image\" src=\"https://github.com/go-fuego/fuego/assets/46993939/18796a59-b2e4-4e01-81d1-88c581de3466\"\u003e\n\n#### Benefits of using Fuego views (controllers returning HTML)\n\n- Never forget to return after an error\n- OpenAPI schema generated, listing all the routes\n- Deserialization and validation are easier\n- Transition to Fuego is easy and fast\n\n\u003c/details\u003e\n\n## Contributing\n\nSee the [contributing guide](CONTRIBUTING.md).\nThanks to [everyone who has contributed][contributors-url] to this project! ❤️\n\n\u003ca href=\"https://github.com/go-fuego/fuego/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=go-fuego/fuego\" alt=\"Graph of contributors\" /\u003e\n\u003c/a\u003e\n\n\u003csmall\u003eMade with [contrib.rocks](https://contrib.rocks)\u003c/small\u003e\n\n## Roadmap\n\nSee the [board](https://github.com/orgs/go-fuego/projects/1).\n\n## Disclaimer for experienced gophers\n\nI know you might prefer to use `net/http` directly,\nbut if having a frame can convince my company to use\nGo instead of Node, I'm happy to use it.\n\n## License\n\n[MIT](./LICENSE.txt)\n\n[gin-gonic-issue]: https://github.com/gin-gonic/gin/issues/155\n[contributors-url]: https://github.com/go-fuego/fuego/graphs/contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-fuego%2Ffuego","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-fuego%2Ffuego","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-fuego%2Ffuego/lists"}