### 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!
```