### Basic Hello World API with Fuego Source: https://github.com/go-fuego/fuego/blob/main/README.md A simple "Hello, World!" example demonstrating how to set up a basic API endpoint using Fuego. This requires importing the Fuego package and defining a GET route. ```go package main import "github.com/go-fuego/fuego" func main() { ss := fuego.NewServer() fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) { return "Hello, World!", nil }) s.Run() } ``` -------------------------------- ### Clone and Run Petstore Example Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/index.md Clone the Fuego repository and run the petstore example locally. This allows for quick iteration on a real-world example. ```bash git clone git@github.com:go-fuego/fuego.git cd fuego/examples/petstore go run . ``` -------------------------------- ### Install Dependencies Source: https://github.com/go-fuego/fuego/blob/main/documentation/README.md Run this command to install project dependencies. ```sh yarn ``` -------------------------------- ### Complete Controller Test Example Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/testing.md A comprehensive example for testing controllers that handle request bodies, query parameters, and validation. It utilizes table-driven tests for better organization and includes setup for query parameters with OpenAPI validation details. ```go // UserSearchRequest represents the search criteria type UserSearchRequest struct { MinAge int `json:"minAge" validate:"gte=0,lte=150" MaxAge int `json:"maxAge" validate:"gte=0,lte=150" NameQuery string `json:"nameQuery" validate:"required" } // SearchUsersController is our controller to test func SearchUsersController(c fuego.ContextWithBody[UserSearchRequest]) (UserSearchResponse, error) { body, err := c.Body() if err != nil { return UserSearchResponse{}, err } // Get pagination from query params page := c.QueryParamInt("page") if page < 1 { page = 1 } // Business logic validation if body.MinAge > body.MaxAge { return UserSearchResponse{}, errors.New("minAge cannot be greater than maxAge") } // ... rest of the controller logic } func TestSearchUsersController(t *testing.T) { tests := []struct { name string body UserSearchRequest setupContext func(*fuego.MockContext[UserSearchRequest]) expectedError string expected UserSearchResponse }{ { name: "successful search", body: UserSearchRequest{ MinAge: 20, MaxAge: 35, NameQuery: "John", }, setupContext: func(ctx *fuego.MockContext[UserSearchRequest]) { // Add query parameters with OpenAPI validation ctx.WithQueryParamInt("page", 1, fuego.ParamDescription("Page number"), fuego.ParamDefault(1)) ctx.WithQueryParamInt("perPage", 20, fuego.ParamDescription("Items per page"), fuego.ParamDefault(20)) }, expected: UserSearchResponse{ // ... expected response }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mock context with the test body ctx := fuego.NewMockContext[UserSearchRequest](tt.body) // Set up context with query parameters if tt.setupContext != nil { tt.setupContext(ctx) } // Call the controller response, err := SearchUsersController(ctx) // Check error cases if tt.expectedError != "" { assert.EqualError(t, err, tt.expectedError) return } // Check success cases assert.NoError(t, err) assert.Equal(t, tt.expected, response) }) } } ``` -------------------------------- ### Start Local Development Server Source: https://github.com/go-fuego/fuego/blob/main/documentation/README.md Starts a local development server. Changes are reflected live without a server restart. ```sh yarn dev ``` -------------------------------- ### Example GET Request with Query Parameter Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md This curl command demonstrates how to send a query parameter to a controller. ```curl curl -X GET http://localhost:9999/?name=MyName # Response: {"name": "MyName"} ``` -------------------------------- ### Install Air CLI Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/03-hot-reload.md Install the `air` command-line tool globally to enable hot reload functionality. ```sh go install github.com/air-verse/air@latest ``` -------------------------------- ### Integrate Standard net/http Middleware and Handlers in Go Source: https://github.com/go-fuego/fuego/blob/main/README.md Utilize standard net/http middleware and handlers within the Fuego framework. This example shows how to apply middleware for setting headers and how to register a standard HTTP handler that automatically gets an OpenAPI route declaration. ```go 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() } ``` -------------------------------- ### Run Hello World Example Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/index.md This command runs a 'Hello World' server using Fuego. It generates a server and provides a URL to view the result in a browser. ```bash go run github.com/go-fuego/fuego/examples/hello-world@latest ``` -------------------------------- ### Instantiate Fuego Engine with Echo Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/alternative-routers-support/echo.md Use `fuego.NewEngine()` to initialize Fuego when integrating with Echo. This replaces the default server setup. ```go engine := fuego.NewEngine() ``` -------------------------------- ### Start Server with Hot Reload Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/03-hot-reload.md Run the `air` command to start your server with hot reload enabled. Changes to your code will be reflected automatically. ```sh air ``` -------------------------------- ### Create Hello World Server Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/01-hello-world.md Define a basic Fuego server with a single GET endpoint that returns 'Hello, World!'. Ensure `go mod tidy` is run before execution. ```go 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() } ``` -------------------------------- ### Custom OpenAPI Options Example Source: https://github.com/go-fuego/fuego/blob/main/README.md Demonstrates how to configure OpenAPI documentation for a POST route using various options like descriptions, summaries, tags, query parameters, and header parameters. ```APIDOC ## POST / ### Description This route does something... ### Method POST ### Endpoint / ### Parameters #### Query Parameters - **name** (string) - Optional - Declares a query parameter with default value. Default: "Carmack" - **page** (integer) - Optional - Page number. Example: "1st page", 1. Example: "42nd page", 42 - **perPage** (integer) - Optional - Number of items per page #### Header Parameters - **Authorization** (string) - Required - Bearer token ### Request Example ```json { "example": "request body" } ``` ### Response #### Success Response (200) - **example** (string) - Description #### Response Example ```json { "example": "response body" } ``` ``` -------------------------------- ### Standard Library Compatibility Example Source: https://github.com/go-fuego/fuego/blob/main/README.md Shows how to integrate standard Go http handlers with Fuego, including the use of standard net/http middleware and automatic OpenAPI route declaration for std handlers. ```APIDOC ## GET /std ### Description Handles requests using a standard net/http handler. ### Method GET ### Endpoint /std ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Body** (string) - "Hello, World!" #### Response Example ``` Hello, World! ``` ``` -------------------------------- ### Python Route with Use Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Use parameter. ```python @Get("/string") string(@Use() use: Use): pass ``` -------------------------------- ### Python Route with File Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a File parameter. ```python @Get("/string") string(@File() file: File): pass ``` -------------------------------- ### Python Route with Static Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Static parameter. ```python @Get("/string") string(@Static() static: Static): pass ``` -------------------------------- ### Controller with Type-Safe Query Parameters (Incoming Syntax) Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md This example shows an upcoming syntax for type-safe query parameter binding using struct tags. ```go type Params struct { Limit int `query:"limit"` Group string `header:"X-User-Group"` } func myController(c fuego.Context[MyInput, Params]) (*MyResponse, error) { params, err := c.Params() if err != nil { return nil, err } return &MyResponse{ Name: params.Group, }, nil } ``` -------------------------------- ### Define Basic HTTP Routes in Fuego Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/routing.md Use standard HTTP methods like Get, Post, Put, Delete, etc., to define routes for your server. Each method takes the server instance, the path, and the handler function. ```go package main import ( "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() fuego.Get(s, "/books", listBooks) fuego.Post(s, "/books", createBook) fuego.Get(s, "/books/{id}", getBook) fuego.Put(s, "/books/{id}", updateBook) fuego.Delete(s, "/books/{id}", deleteBook) s.Run() } ``` -------------------------------- ### Python Route with Redirect Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Redirect parameter. ```python @Get("/string") string(@Redirect() redirect: Redirect): pass ``` -------------------------------- ### Configure OpenAPI Documentation Options in Go Source: https://github.com/go-fuego/fuego/blob/main/README.md Define custom OpenAPI documentation for a POST route using Fuego options. This includes setting descriptions, summaries, tags, deprecation status, query parameters with defaults and examples, and required headers. ```go package main import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" ) func main() { s := fuego.NewServer() // Custom OpenAPI options fuego.Post(s, "/", myController, option.Description("This route does something..."), option.Summary("This is my summary"), option.Tags("MyTag"), // A tag is set by default according to the return type (can be deactivated) option.Deprecated(), // Marks the route as deprecated in the OpenAPI spec option.Query("name", "Declares a query parameter with default value", param.Default("Carmack")), option.Header("Authorization", "Bearer token", param.Required()), optionPagination, optionCustomBehavior, ) s.Run() } var optionPagination = option.Group( option.QueryInt("page", "Page number", param.Default(1), param.Example("1st page", 1), param.Example("42nd page", 42)), option.QueryInt("perPage", "Number of items per page"), ) var optionCustomBehavior = func(r *fuego.BaseRoute) { r.XXX = "YYY" } ``` -------------------------------- ### Python Route with Websocket Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Websocket parameter. ```python @Get("/string") string(@Websocket() websocket: Websocket): pass ``` -------------------------------- ### Python Route Definition Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python using the app decorator. ```python @app.get("/string") def string(string: str): pass ``` -------------------------------- ### Full Fuego Application with OpenAPI, Validation, and Transformations in Go Source: https://github.com/go-fuego/fuego/blob/main/README.md Demonstrates a comprehensive Fuego application featuring automatic OpenAPI generation, request body validation, request/response transformations, and integration with standard net/http handlers. Includes example cURL commands for testing. ```go package main import ( "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"} ``` -------------------------------- ### Python Route with HTML Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting an HTML parameter. ```python @Get("/string") string(@HTML() html: HTML): pass ``` -------------------------------- ### Python Route with Group Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Group parameter. ```python @Get("/string") string(@Group() group: Group): pass ``` -------------------------------- ### Python Route with Text Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Text parameter. ```python @Get("/string") string(@Text() text: Text): pass ``` -------------------------------- ### Python Route with Stream Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Stream parameter. ```python @Get("/string") string(@Stream() stream: Stream): pass ``` -------------------------------- ### Example POST Request with XML Body Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md This curl command shows how to send an XML payload to a controller, which Fuego can also deserialize. ```curl curl -X POST http://localhost:9999/ -d 'My name' -H "Content-Type: application/xml" # Response: {"name": "My name"} ``` -------------------------------- ### Python Route with Bytes Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting a Bytes parameter. ```python @Get("/string") string(@Bytes() bytes: Bytes): pass ``` -------------------------------- ### Example POST Request with JSON Body Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md This curl command demonstrates sending a JSON payload to a controller expecting a MyInput struct. ```curl curl -X POST http://localhost:9999/ -d '{"name": "My name"}' -H "Content-Type: application/json" # Response: {"name": "My name"} ``` -------------------------------- ### Custom Input Transformation and Validation in Fuego Source: https://github.com/go-fuego/fuego/blob/main/README.md Shows how to implement custom input transformation and validation by embedding `fuego.InTransform` in a struct. This example converts the input name to lowercase and checks for a forbidden name. ```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 } ``` -------------------------------- ### Controller without Request Body Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Use the fuego.ContextNoBody interface for controllers that do not expect a request body, such as GET or DELETE requests. ```go func MyController(c fuego.ContextNoBody) (MyResponse, error) { return MyResponse{Name: "My name"}, nil } ``` -------------------------------- ### Return Templ Component from Handler Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/rendering/templ.md Return a Templ component using the `fuego.Templ` return type from a handler function. This example demonstrates fetching and rendering a list of ingredients. ```go import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/examples/full-app-gourmet/store" ) // highlight-next-line func (rs Resource) adminIngredients(c fuego.ContextNoBody) (fuego.Templ, error) { searchParams := components.SearchParams{ Name: c.QueryParam("name"), PerPage: c.QueryParamInt("perPage", 20), Page: c.QueryParamInt("page", 1), URL: "/admin/ingredients", Lang: c.MainLang(), } ingredients, err := rs.IngredientsQueries.SearchIngredients(c.Context(), store.SearchIngredientsParams{ Name: "%" + searchParams.Name + "%", Limit: int64(searchParams.PerPage), Offset: int64(searchParams.Page-1) * int64(searchParams.PerPage), }) if err != nil { return nil, err } // highlight-next-line return admin.IngredientList(ingredients, searchParams), nil } ``` -------------------------------- ### Output Transformation for User Response Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/transformation.md Implement the `OutTransform` method on a struct to modify data before it's serialized. This example masks sensitive data and generates a full name field. ```go package main import ( "context" "strings" "github.com/go-fuego/fuego" ) type UserResponse struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` FullName string `json:"full_name"` } func (u *UserResponse) OutTransform(ctx context.Context) error { // Mask the last name for privacy if len(u.LastName) > 0 { u.LastName = u.LastName[:1] + "***" } // Generate the full name from first and last name u.FullName = u.FirstName + " " + u.LastName // Use the context to get the request ID if reqID, ok := RequestIDFromContext(ctx); ok { u.FullName += " (Request ID: " + reqID + ")" } return nil } var _ fuego.OutTransformer = (*UserResponse)(nil) // Ensure *UserResponse implements fuego.OutTransformer ``` ```go func getUser(c fuego.ContextNoBody) (UserResponse, error) { // Get user from database or other source user := UserResponse{ FirstName: "John", LastName: "Doe", } // The OutTransform method will be called automatically before serialization // After transformation, user.FullName will be "John Doe" and user.LastName will be "D***" return user, nil } ``` -------------------------------- ### Configure Fuego Server with Options Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/options.md Demonstrates how to initialize a Fuego server with custom address and OpenAPI configurations. ```go package main import "github.com/go-fuego/fuego" func main() { ss := fuego.NewServer( fuego.WithAddr("localhost:8080"), fuego.WithEngineOptions( fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{ DisableSwaggerUI: true, }), ), ) fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) { return "Hello, World!", nil }) s.Run() } ``` -------------------------------- ### Initialize Go Module Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/01-hello-world.md Create a `go.mod` file to manage dependencies for your Fuego project. ```bash go mod init hello-fuego ``` -------------------------------- ### Get Request Header Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Access request headers using the c.Header() method within a controller. ```go func MyController(c fuego.ContextNoBody) (MyResponse, error) { value := c.Header("X-My-Header") return MyResponse{}, nil } ``` -------------------------------- ### Go Hello World Server Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/index.md A basic Fuego server that responds with 'Hello, World!' to requests on the root path. Requires Go v1.22 or above. ```go package main import ( "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() fuego.Get(s, "/", helloWorld) s.Run() } func helloWorld(c fuego.ContextNoBody) (string, error) { return "Hello, World!", nil } ``` -------------------------------- ### Initialize Air Configuration Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/03-hot-reload.md Create a default `.air.toml` configuration file to customize hot reload behavior. ```sh air init ``` -------------------------------- ### Create Project Directory Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/01-hello-world.md Initialize a new project directory for your Fuego application. ```bash mkdir hello-fuego cd hello-fuego ``` -------------------------------- ### Python Route with Error Parameter Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Defines a GET route for '/string' in Python, accepting an Error parameter. ```python @Get("/string") string(@Error() error: Error): pass ``` -------------------------------- ### Run Fuego Server Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/01-hello-world.md Tidy up dependencies and run the Fuego server locally. ```bash go mod tidy go run . ``` -------------------------------- ### Define Route Options with Parameters and Middlewares Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/options.md Register a route with query parameters, summary, description, tags, and custom options. ```go package main import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" ) type MyInput struct { Name string `json:"name"` } type MyResponse struct { Name string `json:"name"` } func myController(c fuego.ContextWithBody[MyInput]) (*MyResponse, error) { name := c.QueryParam("name") return &MyResponse{ Name: name, }, } var myReusableOption = option.Group( option.QueryInt("per_page", "Number of items per page", param.Default(100), param.Example("100 per page", 100)), option.QueryInt("page", "Page number", param.Default(1), param.Example("page 9", 9)), ) func myCustomOption(r *fuego.BaseRoute) { r.XXX = "YYY" // Direct access to the route struct to inject custom behavior } func main() { s := fuego.NewServer() fuego.Get(s, "/", myController, option.Query("name", "Name of the user", param.Required(), param.Example("example 1", "Napoleon")), option.Summary("Name getting route"), option.Description("This is the longdescription of the route"), option.Tags("Name", "Getting"), myCustomOption, myReusableOption, ) s.Run() } ``` -------------------------------- ### Test a Simple Controller with MockContext Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/testing.md Demonstrates basic usage of MockContext to test a controller. Create a mock context with a request body and query parameters, then call your controller and assert the results. ```go func TestMyController(t *testing.T) { // Create a new mock context with the request body ctx := fuego.NewMockContext(MyRequestType{ Name: "John", Age: 30, }) // Add query parameters ctx.SetQueryParamInt("page", 1) // Call your controller response, err := MyController(ctx) // Assert the results assert.NoError(t, err) assert.Equal(t, expectedResponse, response) } ``` -------------------------------- ### Add Server-Level Middlewares using Use Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/middlewares.md Apply middlewares to the entire server using the `fuego.Use` function. These middlewares will be applied to all routes handled by the server. ```go package main import ( "net/http" "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() // Add a middleware to the whole server fuego.Use(s, myMiddleware) fuego.Get(s, "/", myController) s.Run() } ``` -------------------------------- ### Add Global Middlewares using Server Options Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/middlewares.md Register global middlewares using `fuego.WithGlobalMiddlewares` when creating the server. These middlewares are applied to all requests, including those for non-existent routes. ```go package main import ( "net/http" "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer( // Add a global middleware fuego.WithGlobalMiddlewares(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Hello", "World") // Do something before the request next.ServeHTTP(w, r) // Do something after the request }) }), ) fuego.Get(s, "/my-route", myController) // Here, the global middleware is applied s.Run() } ``` -------------------------------- ### Add Route Middlewares using Options Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/middlewares.md Register middlewares for a single route by providing them as options during route registration. They are applied in the order they are declared. ```go package main import ( "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() // Declare the middlewares after the route handler fuego.Get(s, "/", myController, option.QueryInt("page", "The page number"), option.Middleware(middleware1), option.Middleware(middleware2, middleware3), ) s.Run() } ``` -------------------------------- ### Get Request Cookie in Go Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Retrieves a cookie from the incoming request using the provided context. Ensure the cookie name is correct. ```go func MyController(c fuego.ContextNoBody) (MyResponse, error) { value := c.Cookie("my-cookie") return MyResponse{}, nil } ``` -------------------------------- ### Generate Controller with In-Memory Service Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/02-crud.md Use the `--with-service` flag to generate a controller along with a basic in-memory service implementation. This is useful for quick testing and development. ```bash fuego controller --with-service books ``` -------------------------------- ### Implement Wildcard Path Parameters in Fuego Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/routing.md Use the `{param...}` syntax to create catch-all routes that match any remaining path segments. The matched segments can be retrieved using `c.PathParam("param")`. ```go package main import ( "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() fuego.Get(s, "/files/{path...}", getFile) s.Run() } func getFile(c fuego.ContextNoBody) (string, error) { path := c.PathParam("path") return "File path: " + path, nil } ``` -------------------------------- ### File Response Handling Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Serves static files directly. Use for serving assets like CSS, JS, or images. ```go File(string) ``` ```go http.ServeFile(w, r, string) ``` ```go c.File(string) ``` -------------------------------- ### Custom Validation with Input Transformation Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/transformation.md Utilize the `InTransform` method for custom validation logic that goes beyond standard validation rules. This example prevents a reserved name combination. ```go func (u *User) InTransform(ctx context.Context) error { // Normalize data u.FirstName = strings.TrimSpace(u.FirstName) u.LastName = strings.TrimSpace(u.LastName) // Custom validation if u.FirstName == "Admin" && u.LastName == "User" { return errors.New("reserved name combination") } return nil } ``` -------------------------------- ### Add Options to Fuego Routes Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/routing.md Enhance routes with options for OpenAPI documentation (e.g., summary, description, tags) or to apply middleware. Query parameters can also be defined with types and defaults. ```go package main import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/option" "github.com/go-fuego/fuego/param" ) func main() { s := fuego.NewServer() fuego.Get(s, "/books", listBooks, option.Summary("List all books"), option.Description("Returns a list of all books in the library"), option.Tags("Books"), option.QueryInt("page", "Page number", param.Default(1)), option.QueryInt("limit", "Items per page", param.Default(10)), ) s.Run() } ``` -------------------------------- ### Input Transformation for User Struct Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/transformation.md Implement the `InTransform` method on a struct to modify data before it's unmarshaled. This example normalizes first names to uppercase and trims last names. ```go package main import ( "context" "strings" "github.com/go-fuego/fuego" ) type User struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` } func (u *User) InTransform(ctx context.Context) error { u.FirstName = strings.ToUpper(u.FirstName) u.LastName = strings.TrimSpace(u.LastName) return nil } var _ fuego.InTransformer = (*User)(nil) // Ensure *User implements fuego.InTransformer // This check is a classic example of Go's interface implementation check and we highly recommend to use it ``` ```go func echoCapitalized(c fuego.ContextWithBody[User]) (User, error) { user, err := c.Body() if err != nil { return User{}, err } // user.FirstName is in uppercase return user, nil } ``` -------------------------------- ### Static File Serving Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Serves static files from a directory. Use for web assets. ```go Static(string, string) ``` ```go mux.NewRouter().PathPrefix(string).Handler(http.StripPrefix(string, http.FileServer(http.Dir(string)))) ``` ```go c.Static(string, string) ``` -------------------------------- ### Registering a Controller Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Controllers are registered with specific HTTP methods and paths using functions like fuego.Get. ```go fuego.Get(s, "/", MyController) ``` -------------------------------- ### Build Static Website Content Source: https://github.com/go-fuego/fuego/blob/main/documentation/README.md Generates static content for hosting. The output is placed in the 'build' directory. ```sh yarn build ``` -------------------------------- ### Configuring OpenAPI Output and Behavior Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/openapi.md Customize the OpenAPI specification's output paths, enable/disable features like Swagger UI, local saving, and message logging using `WithOpenAPIConfig`. ```go package main import ( "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer( fuego.WithEngineOptions( fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{ Disabled: false, // If true, the server will not serve nor generate any OpenAPI resources DisableSwaggerUI: false, // If true, the server will not serve the swagger ui DisableLocalSave: false, // If true, the server will not save the openapi json spec locally DisableMessages: false, // If true, the engine will not print messages PrettyFormatJSON: true, // Pretty prints the OpenAPI spec with proper JSON indentation SwaggerURL: "/swagger", // URL to serve the swagger ui SpecURL: "/swagger/openapi.json", // URL to serve the openapi json spec JSONFilePath: "doc/openapi.json", // Local path to save the openapi json spec UIHandler: fuego.DefaultOpenAPIHandler, // Custom UI handler }), ), ) fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) { return "Hello, World!", nil }) s.Run() } ``` -------------------------------- ### Add Group-Level Middlewares using Route Options Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/middlewares.md Apply middlewares to a group of routes by providing them as options when creating the group. This offers an alternative to the `fuego.Use` method for group-level middleware. ```go package main import ( "net/http" "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() // Add a middleware to a group of routes api := fuego.Group(s, "/api", option.Middleware(myMiddleware), ) // Requests to /api will go through the middleware fuego.Get(api, "/", myController) // Requests to / will NOT! go through the middleware fuego.Get(s, "/", myController) s.Run() } ``` -------------------------------- ### Add Group-Level Middlewares using Use Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/middlewares.md Apply middlewares to a specific group of routes using `fuego.Use` on a `fuego.Group`. Only routes within this group will be affected. ```go package main import ( "net/http" "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() // Add a middleware to a group of routes api := fuego.Group(s, "/api") fuego.Use(api, myMiddleware) // Requests to /api will go through the middleware fuego.Get(api, "/", myController) // Requests to / will NOT! go through the middleware fuego.Get(s, "/", myController) s.Run() } ``` -------------------------------- ### Customize Engine Options Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/options.md Configure engine-level options such as error handling and OpenAPI UI customization. ```go s := fuego.NewServer( fuego.WithEngineOptions( fuego.WithErrorHandler(func(err error) error { return fmt.Errorf("my wrapper: %w", err) }), fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{ UIHandler: func(specURL string) http.Handler { return dummyMiddleware(fuego.DefaultOpenAPIHandler(specURL)) }, }), ), ) ``` -------------------------------- ### Replace Echo Controllers with Fuego Controllers Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/alternative-routers-support/echo.md Incrementally replace Echo controllers with Fuego controllers using `fuegoecho.Get`. This enables automatic OpenAPI documentation, validation, and content-negotiation for individual routes. ```go engine.Get("/users", fuegoController) ``` -------------------------------- ### Wrap Echo Routes with Fuego OpenAPI Declaration Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/alternative-routers-support/echo.md Replace `echo.GET` with `fuegoecho.GetEcho` to wrap existing Echo routes. This allows Fuego to generate OpenAPI documentation without altering controllers. ```go engine.GetEcho(echo.GET, "/users", echoHandler) ``` -------------------------------- ### Deploy Website (SSH) Source: https://github.com/go-fuego/fuego/blob/main/documentation/README.md Deploys the website using SSH. This command builds the static content and pushes it to the 'gh-pages' branch. ```sh USE_SSH=true yarn deploy ``` -------------------------------- ### Static Files Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Serves static files from a specified directory. ```APIDOC ## Static Files ### Description Serves static files from a given directory under a specified URL prefix. ### Method `Static(string, string)` ### Endpoint `c.Static(string, string)` ### Parameters - **urlPrefix** (string) - The URL prefix to serve static files from. - **rootPath** (string) - The root directory containing the static files. ``` -------------------------------- ### Render HTML Template in Fuego Handler Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/rendering/std.md Use `fuego.HTML` as the return type for your handler and call `c.Render()` with the template name and data. This snippet demonstrates fetching data and passing it to a partial template for rendering. ```go import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/examples/full-app-gourmet/store/types" ) // highlight-next-line func (rs Resource) unitPreselected(c fuego.ContextNoBody) (fuego.CtxRenderer, error) { id := c.QueryParam("IngredientID") ingredient, err := rs.IngredientsQueries.GetIngredient(c.Context(), id) if err != nil { return "", err } // highlight-start return c.Render("preselected-unit.partial.html", fuego.H{ "Units": types.UnitValues, "SelectedUnit": ingredient.DefaultUnit, }) // highlight-end } ``` -------------------------------- ### HTML Response Handling Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Handles HTML responses using template execution. Use when rendering HTML content for the client. ```go HTML(int, string, interface{}) ``` ```go template.Execute(w, data) ``` ```go c.HTML(int, string, interface{}) ``` -------------------------------- ### Set Route Options at Server Level Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/options.md Define route options at the server level to be inherited by all registered routes. ```go package main import ( "github.com/go-fuego/fuego" "github.com/go-fuego/fuego/option" ) func main() { s := fuego.NewServer( fuego.WithRouteOptions( option.Summary("Pets operations"), option.Description("Operations about pets"), option.Tags("pets"), ), ) fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) { return "Hello, World!", nil }) } ``` -------------------------------- ### Set Server Address with WithAddr Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/options.md Use the `WithAddr` option to specify the network address for the Fuego server. ```go import "github.com/go-fuego/fuego" func main() { s := fuego.NewServer( fuego.WithAddr("localhost:8080"), ) } ``` -------------------------------- ### Inject Controller into Server Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/02-crud.md Declare and inject the controller resources into the Fuego server. This makes the defined routes available. ```go package main import ( "github.com/go-fuego/fuego" // ADD NEXT LINE "hello-fuego/controller" ) func main() { s := fuego.NewServer() // .... // Declare the resource booksResources := controller.BooksResources{ BooksService: controller.RealBooksService{}, // Other services & dependencies, like a DB etc. } // Plug the controllers into the server booksResources.Routes(s) s.Run() } ``` -------------------------------- ### Deploy Website (No SSH) Source: https://github.com/go-fuego/fuego/blob/main/documentation/README.md Deploys the website without using SSH. Replace '' with your actual GitHub username. This command builds the static content and pushes it to the 'gh-pages' branch. ```sh GIT_USER= yarn deploy ``` -------------------------------- ### Controller with Dynamic Query Parameters Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Access query parameters using c.QueryParam(). Parameters are declared at route registration for OpenAPI generation and validation. ```go package main import ( "github.com/go-fuego/fuego" ) type MyInput struct { Name string `json:"name"` } func myController(c fuego.ContextWithBody[MyInput]) (*MyResponse, error) { name := c.QueryParam("name") return &MyResponse{ Name: name, }, nil } var myReusableOption = option.Group( option.QueryInt("per_page", "Number of items per page", param.Default(100), param.Example("100 per page", 100)), option.QueryInt("page", "Page number", param.Default(1), param.Example("page 9", 9)), ) func main() { s := fuego.NewServer() fuego.Get(s, "/", myController, option.Query("name", "Name of the user", param.Required(), param.Example("example 1", "Napoleon")), myReusableOption, ) s.Run() } ``` -------------------------------- ### Use Middleware Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Applies middleware to the router or a specific group. ```APIDOC ## Use Middleware ### Description Applies a middleware function to the router or a route group. ### Method `Use(func())` ### Endpoint `c.Use(func())` ### Parameters - **middleware** (func()) - The middleware function to apply. ``` -------------------------------- ### Implement Service Interface in Controller Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/02-crud.md Modify the generated controller file to implement the service interface. This involves defining the service interface and its concrete implementation, then injecting it into the controller. ```go package controller import ( "github.com/go-fuego/fuego" ) type BooksResources struct { // Use a concrete struct that implements the service (BooksService -> RealBooksService) BooksService RealBooksService } type Books struct { ID string `json:"id"` Name string `json:"name"` } // .... // .... type BooksService interface { GetBooks(id string) (Books, error) CreateBooks(BooksCreate) (Books, error) GetAllBooks() ([]Books, error) UpdateBooks(id string, input BooksUpdate) (Books, error) DeleteBooks(id string) (any, error) } // Implement the BooksService interface type RealBooksService struct { // Embed the interface to satisfy it. // This pattern is just there to make the code compile but you should implement all methods. BooksService } func (s RealBooksService) GetBooks(id string) (Books, error) { return Books{ ID: id, Name: "Test book data", }, nil } // TODO: Other BooksService interface implementations // END OF CODE BLOCK ``` -------------------------------- ### Websocket Handling Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Handles websocket connections. Use for real-time, bi-directional communication. ```go Websocket(string, func()) ``` ```go mux.NewRouter().PathPrefix(string).Handler(http.StripPrefix(string, http.FileServer(http.Dir(string)))) ``` ```go c.Websocket(string, func()) ``` -------------------------------- ### Simple POST API with Request Body and Validation Source: https://github.com/go-fuego/fuego/blob/main/README.md Demonstrates a POST endpoint that accepts a JSON request body with validation. The `MyInput` struct uses `json` tags for serialization and `validate` tags for input validation. OpenAPI documentation is automatically generated. ```go 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, "/user/{user}", myController) s.Run() } func myController(c fuego.ContextWithBody[MyInput]) (*MyOutput, error) { body, err := c.Body() if err != nil { return nil, err } return &MyOutput{Message: "Hello, " + body.Name}, nil } ``` -------------------------------- ### Controller for Binary Request Body Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/controllers.md Handle raw byte slices as the request body using `[]byte` as the receiver type. Ensure the Content-Type is set to `application/octet-stream`. ```go fuego.Put(s, "/blob", func(c fuego.ContextWithBody[[]byte]) (any, error) { body, err := c.Body() if err != nil { return nil, err } return body, nil }) ``` -------------------------------- ### Use Standard HTTP Handlers with Fuego Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/routing.md Fuego allows you to use standard `http.Handler` functions for your routes by using methods like `GetStd`, `PostStd`, etc. ```go package main import ( "net/http" "github.com/go-fuego/fuego" ) func main() { s := fuego.NewServer() fuego.GetStd(s, "/standard", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello from standard HTTP handler")) }) s.Run() } ``` -------------------------------- ### Middleware Integration Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Applies middleware functions to handle requests. Use for cross-cutting concerns like logging or authentication. ```go Use(func()) ``` ```go mux.NewRouter().Use(func()) ``` ```go c.Use(func()) ``` -------------------------------- ### Manually Define CRUD Routes Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/02-crud.md Manually define all CRUD routes for the books resource in the main application file. This provides explicit control over each route. ```go package main import ( "github.com/go-fuego/fuego" "hello-fuego/controller" ) func main() { s := fuego.NewServer() // List all books fuego.Get(s, "/books", controller.GetBooks) // Create a new book fuego.Post(s, "/books", controller.CreateBook) // Get a book by id fuego.Get(s, "/books/:id", controller.GetBook) // Update a book by id fuego.Put(s, "/books/:id", controller.UpdateBook) // Update a book by id fuego.Patch(s, "/books/:id", controller.UpdateBook) // Delete a book by id fuego.Delete(s, "/books/:id", controller.DeleteBook) s.Run() } ``` -------------------------------- ### Controller Functions for Manual Routes Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/tutorials/02-crud.md Implement the controller functions for each manually defined route. These functions handle the request logic and return appropriate responses. ```go package controller import ( "github.com/go-fuego/fuego" ) type Book struct { ID string `json:"id"` Title string `json:"title"` } type BookToCreate struct { Title string `json:"title"` } func GetBooks(c fuego.ContextNoBody) ([]Book, error) { // Your code here return nil, nil } func CreateBook(c fuego.ContextWithBody[BookToCreate]) (Book, error) { // Your code here return Book{}, nil } func GetBook(c fuego.ContextNoBody) (Book, error) { // Your code here return Book{}, nil } func UpdateBook(c fuego.ContextWithBody[Book]) (Book, error) { // Your code here return Book{}, nil } func DeleteBook(c fuego.ContextNoBody) (any, error) { // Your code here return nil, nil } ``` -------------------------------- ### Redirect Handling Source: https://github.com/go-fuego/fuego/blob/main/BENCHMARK.md Handles HTTP redirects. Use to send clients to a different URL. ```go Redirect(int, string) ``` ```go http.Redirect(w, r, string, int) ``` ```go c.Redirect(int, string) ``` -------------------------------- ### Using Fuego HTTPError Directly Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/errors.md Instantiate `fuego.HTTPError` directly to create a structured error response with a custom title, detail message, and HTTP status code. ```go err := fuego.HTTPError{ Title: "Custom error", Detail: "This is a custom error", Status: http.StatusTeapot, } ``` -------------------------------- ### Automatic Serialization with Content Negotiation Source: https://github.com/go-fuego/fuego/blob/main/documentation/docs/guides/serialization.md Return data from your controller, and Fuego automatically serializes it based on the client's Accept header. Defaults to JSON if no header is provided. ```go type MyReturnType struct { Message string `json:"message"` } func helloWorld(c fuego.ContextNoBody) (MyReturnType, error) { return MyReturnType{Message: "Hello, World!"}, nil } // curl request: curl -X GET http://localhost:8080/ -H "Accept: application/json" // response: {"message":"Hello, World!"} // curl request: curl -X GET http://localhost:8080/ -H "Accept: application/xml" // response: Hello, World! ```