Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/go-fuego/fuego
Golang Fuego - web framework generating OpenAPI 3 spec from source code
https://github.com/go-fuego/fuego
fuego golang http-server openapi
Last synced: 15 days ago
JSON representation
Golang Fuego - web framework generating OpenAPI 3 spec from source code
- Host: GitHub
- URL: https://github.com/go-fuego/fuego
- Owner: go-fuego
- License: mit
- Created: 2023-10-17T15:36:43.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2024-04-23T23:07:18.000Z (2 months ago)
- Last Synced: 2024-04-24T00:25:11.368Z (2 months ago)
- Topics: fuego, golang, http-server, openapi
- Language: Go
- Homepage: https://go-fuego.github.io/fuego/
- Size: 1.4 MB
- Stars: 554
- Watchers: 3
- Forks: 27
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
- Security: security.go
Lists
- awesome-stars - go-fuego/fuego - Golang Fuego - web framework generating OpenAPI 3 spec from source code (Go)
README
![]()
# Fuego 🔥
[![Go Reference](https://pkg.go.dev/badge/github.com/go-fuego/fuego.svg)](https://pkg.go.dev/github.com/go-fuego/fuego)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-fuego/fuego)](https://goreportcard.com/report/github.com/go-fuego/fuego)
[![Coverage Status](https://coveralls.io/repos/github/go-fuego/fuego/badge.svg?branch=main)](https://coveralls.io/github/go-fuego/fuego?branch=main)
[![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23fuego-%237289da?)](https://discord.com/invite/s233GcZqFT)> The framework for busy Go developers
**Build your API or web application in minutes!**
Go framework generating OpenAPI documentation from code. Inspired by Nest, built for Go developers.
Also empowers `html/template`, `a-h/templ` and `maragudk/gomponents`: see [the example](./examples/full-app-gourmet) - actually running [in prod](https://gourmet.quimerch.com)!
## Why Fuego?
Chi, Gin, Fiber and Echo are great frameworks. But since they were designed a long time ago, [their current API does not allow them](https://github.com/gin-gonic/gin/issues/155) to deduce OpenAPI types from signatures, things that are now possible with generics. Fuego offers a lot of "modern Go based" features that make it easy to develop APIs and web applications.
## Features
- **OpenAPI**: Fuego automatically generates OpenAPI documentation from **code** - _not from comments nor yaml files!_
- **`net/http` compatible**: Fuego is built on top of `net/http`, so you can use any `http.Handler` middleware or handler! Fuego also supports `log/slog`, `context` and `html/template`
- **Routing**: Fuego provides a simple API for the Go 1.22 `net/http`
- **Serialization/Deserialization**: Fuego automatically serializes and deserializes JSON, XML and HTML Forms based on user-provided structs (or not, if you want to do it yourself)
- **Validation**: Fuego provides a simple and fast validator based on `go-playground/validator`
- **Transformation**: easily transform your data by implementing the `fuego.InTransform` and `fuego.OutTransform` interfaces - also useful for **validation**
- **Middlewares**: easily add a custom `net/http` middleware or use the provided middlewares.
- **Error handling**: Fuego provides centralized error handling with the standard [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457).
- **Rendering**: Fuego provides a simple and fast rendering system based on `html/template` - you can still also use your own template system like `templ` or `gomponents`## Examples
### Hello World
```go
package mainimport "github.com/go-fuego/fuego"
func main() {
s := fuego.NewServer()fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) {
return "Hello, World!", nil
})s.Run()
}
```### Simple POST
```go
package mainimport "github.com/go-fuego/fuego"
type MyInput struct {
Name string `json:"name" validate:"required"`
}type MyOutput struct {
Message string `json:"message"`
}func main() {
s := fuego.NewServer()// Automatically generates OpenAPI documentation for this route
fuego.Post(s, "/", func(c *fuego.ContextWithBody[MyInput]) (MyOutput, error) {
body, err := c.Body()
if err != nil {
return MyOutput{}, err
}return MyOutput{
Message: "Hello, " + body.Name,
}, nil
})s.Run()
}
```### With transformation & custom validation
```go
type MyInput struct {
Name string `json:"name" validate:"required"`
}// Will be called just before returning c.Body()
func (r *MyInput) InTransform(context.Context) error {
r.Name = strings.ToLower(r.Name)if r.Name == "fuego" {
return errors.New("fuego is not a valid name for this input")
}return nil
}```
### More OpenAPI documentation
```go
package mainimport "github.com/go-fuego/fuego"
func main() {
s := fuego.NewServer()// Custom OpenAPI options that cannot be deduced by the controller signature
fuego.Post(s, "/", myController).
Description("This route does something").
Summary("This is my summary").
Tags("MyTag"). // A tag is set by default according to the return type (can be desactivated)
Deprecated()s.Run()
}
```### Std lib compatibility
```go
package mainimport (
"net/http"
"github.com/go-fuego/fuego"
)func main() {
s := fuego.NewServer()// Standard net/http middleware
fuego.Use(s, func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Hello", "World")
next.ServeHTTP(w, r)
})
})// Standard net/http handler with automatic OpenAPI route declaration
fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})s.Run()
}
```All features
```go
package mainimport (
"context"
"errors"
"net/http"
"strings"chiMiddleware "github.com/go-chi/chi/v5/middleware"
"github.com/go-fuego/fuego"
"github.com/rs/cors"
)type Received struct {
Name string `json:"name" validate:"required"`
}type MyResponse struct {
Message string `json:"message"`
BestFramework string `json:"best"`
}func main() {
s := fuego.NewServer(
fuego.WithAddr("localhost:8088"),
)fuego.Use(s, cors.Default().Handler)
fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css"))// Fuego 🔥 handler with automatic OpenAPI generation, validation, (de)serialization and error handling
fuego.Post(s, "/", func(c *fuego.ContextWithBody[Received]) (MyResponse, error) {
data, err := c.Body()
if err != nil {
return MyResponse{}, err
}c.Response().Header().Set("X-Hello", "World")
return MyResponse{
Message: "Hello, " + data.Name,
BestFramework: "Fuego!",
}, nil
})// Standard net/http handler with automatic OpenAPI route declaration
fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})s.Run()
}// InTransform will be called when using c.Body().
// It can be used to transform the entity and raise custom errors
func (r *Received) InTransform(context.Context) error {
r.Name = strings.ToLower(r.Name)
if r.Name == "fuego" {
return errors.New("fuego is not a name")
}
return nil
}// OutTransform will be called before sending data
func (r *MyResponse) OutTransform(context.Context) error {
r.Message = strings.ToUpper(r.Message)
return nil
}
``````bash
curl http://localhost:8088/std
# Hello, World!
curl http://localhost:8088 -X POST -d '{"name": "Your Name"}' -H 'Content-Type: application/json'
# {"message":"HELLO, YOUR NAME","best":"Fuego!"}
curl http://localhost:8088 -X POST -d '{"name": "Fuego"}' -H 'Content-Type: application/json'
# {"error":"cannot transform request body: cannot transform request body: fuego is not a name"}
```## From net/http to Fuego in 10s
https://github.com/go-fuego/fuego/assets/46993939/7438a71c-75a4-4e88-a584-71da6362c575
Views
#### Before
#### After
#### Diff
#### Benefits of using Fuego views (controllers returning HTML)
- Never forget to return after an error
- OpenAPI schema generated, listing all the routes
- Deserialization and validation are more easy
- Transition to Fuego is easy and fast## Contributing
See the [contributing guide](CONTRIBUTING.md). Thanks to [everyone who has contributed](https://github.com/go-fuego/fuego/graphs/contributors) to this project! ❤️
## Roadmap
See the [board](https://github.com/orgs/go-fuego/projects/1).
## Disclaimer for experienced gophers
I know you might prefer to use `net/http` directly, but if having a frame can convince my company to use Go instead of Node, I'm happy to use it.
## License
[MIT](./LICENSE.txt)