Categorygithub.com/fourcorelabs/fuego
modulepackage
0.1.27
Repository: https://github.com/fourcorelabs/fuego.git
Documentation: pkg.go.dev

# README

Fuego Logo

Fuego 🔥

Go Reference Go Report Card Coverage Status Discord Gophers

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 - actually running in prod!

Sponsors

Fuego is proudly sponsored by Zuplo, that provides a Fuego integration!

Fuego Logo

Zuplo allows you to secure your Fuego API, scale it globally, generate documentation from your OpenAPI, and monetize your users.

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 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!
  • 100% net/http compatible (no lock-in): 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 router is based on Go 1.22 net/http, with grouping and middleware support
  • 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 custom 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.
  • 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

package main

import "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

package main

import "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

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

package main

import "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 deactivated)
		Deprecated()

	s.Run()
}

Std lib compatibility

package main

import (
	"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()
}

Real-world examples

Please see the /examples folder for more examples.

All features
package main

import (
	"context"
	"errors"
	"net/http"
	"strings"

	chiMiddleware "github.com/go-chi/chi/v5/middleware"
	"github.com/rs/cors"

	"github.com/go-fuego/fuego"
)

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
}
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

image

After

image

Diff

image

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 easier
  • Transition to Fuego is easy and fast

Contributing

See the contributing guide. Thanks to everyone who has contributed to this project! ❤️

Roadmap

See the board.

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

# Packages

No description provided by the author
No description provided by the author

# Functions

Capture all methods (GET, POST, PUT, PATCH, DELETE) and register a controller.
No description provided by the author
AuthWall is a middleware that checks if the user is authorized.
AuthWallRegex is a middleware that checks if the user is authorized.
AuthWallRegexp is a middleware that checks if the user is authorized.
Helper function to create a DataOrTemplate return item without specifying the type.
No description provided by the author
No description provided by the author
No description provided by the author
ErrorHandler is the default error handler used by the framework.
FuegoHandler converts a Fuego controller into a http.HandlerFunc.
No description provided by the author
No description provided by the author
GetToken returns the validated token from the context, if found.
No description provided by the author
No description provided by the author
NewContext returns a new context.
No description provided by the author
No description provided by the author
NewServer creates a new server with the given options.
No description provided by the author
No description provided by the author
No description provided by the author
Post
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
ReadJSON reads the request body as JSON.
ReadString reads the request body as string.
ReadURLEncoded reads the request body as HTML Form.
ReadXML reads the request body as XML.
ReadYAML reads the request body as YAML.
No description provided by the author
RegisterOpenAPIOperation registers an OpenAPI operation.
Send sends a response.
SendHTMLError sends a HTML response.
SendJSONError sends a JSON error response.
SendText sends a HTML response.
SendTextError sends a Text response.
SendXMLError sends a XML error response.
SendYAMLError sends a YAML error response.
TokenFromContext returns the validated token from the context, if found.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
WithCorsMiddleware registers a middleware to handle CORS.
No description provided by the author
WithDisallowUnknownFields sets the DisallowUnknownFields option.
No description provided by the author
WithErrorSerializer sets a custom serializer of type ErrorSender that overrides the default one.
No description provided by the author
No description provided by the author
No description provided by the author
WithGlobalResponseTypes adds default response types to the server.
WithLogHandler sets the log handler of the server.
No description provided by the author
No description provided by the author
WithoutAutoGroupTags disables the automatic grouping of routes by tags.
WithoutLogger disables the default logger.
WithoutStartupMessages disables the startup message.
No description provided by the author
No description provided by the author
No description provided by the author
WithSerializer sets a custom serializer of type Sender that overrides the default one.
No description provided by the author
WithTemplateFS sets the filesystem used to load templates.
WithTemplateGlobs loads templates matching the given patterns from the server filesystem.
WithTemplates loads the templates used to render HTML.
WithValidator sets the validator to be used by the fuego server.
No description provided by the author
WithXML sets the serializer to XML Deprecated: fuego supports automatic XML serialization when using the header "Accept: application/xml".

# Constants

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Variables

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
SendError sends an error.
SendHTML sends a HTML response.
SendJSON sends a JSON response.
SendXML sends a XML response.
SendYAML sends a YAML response.

# Structs

No description provided by the author
ContextNoBody is used when the controller does not have a body.
ContextWithBody is the same as fuego.ContextNoBody, but has a Body.
DataOrTemplate is a struct that can return either data or a template depending on the asked type.
No description provided by the author
No description provided by the author
HTTPError is the error response used by the serialization part of the framework.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Security holds the key to sign the JWT tokens, and configuration information.
No description provided by the author
StdRenderer renders a template using the standard library templating engine.
Timing is a struct to represent a server timing.

# Interfaces

CtxRenderer is an interface that can be used to render a response.
ErrorWithStatus is an interface that can be implemented by an error to provide additional information about the error.
InTransformer is an interface for entities that can be transformed.
No description provided by the author
No description provided by the author
OutTransformer is an interface for entities that can be transformed.
Renderer can be used with [github.com/maragudk/gomponents] Example: func getRecipes(ctx fuego.ContextNoBody) (fuego.CtxRenderer, error) { recipes, err := ctx.store.GetRecipes(ctx.Context()) if err != nil { return nil, err } return recipeComponent(recipes), nil // recipeComponent is gomponents component }.

# Type aliases

BadRequestError is an error used to return a 400 status code.
ConflictError is an error used to return a 409 status code.
No description provided by the author
ForbiddenError is an error used to return a 403 status code.
Gomponent is a shortcut for [Renderer], which can be used with [github.com/maragudk/gomponents].
H is a shortcut for map[string]any.
HTML is a marker type used to differentiate between a string response and an HTML response.
NotFoundError is an error used to return a 404 status code.
No description provided by the author
No description provided by the author
Templ is a shortcut for [CtxRenderer], which can be used with [github.com/a-h/templ].
UnauthorizedError is an error used to return a 401 status code.