### Clone and Run Flamingo Hello World
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/0. Introduction/1. Getting Started.md
Commands to clone the Flamingo hello-world example repository and execute the application using Go commands. This requires Go 1.13 or higher and uses Go modules for dependency management.
```bash
git clone git@github.com:i-love-flamingo/example-helloworld.git
cd example-helloworld
go run main.go
go run main.go serve
```
--------------------------------
### Initialize New Flamingo Project
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/0. Introduction/1. Getting Started.md
Steps to create a new directory, initialize a Go module, and define the main entry point for a Flamingo application. This serves as the foundation for building custom Flamingo projects.
```bash
mkdir hello-flamingo && cd hello-flamingo
go mod init flamingo.me/hello-flamingo
```
```go
package main
import (
"flamingo.me/flamingo/v3"
)
func main() {
flamingo.App(nil)
}
```
```bash
go run main.go
```
--------------------------------
### Running a Flamingo Project
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/2. Flamingo Project Structure.md
Demonstrates how to execute the main entry point of a Flamingo project. It shows how to list available commands and how to run the 'serve' command to start the application.
```bash
go run main.go
go run main.go serve
```
--------------------------------
### Fake Login Template Example
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/oauth/Readme.md
This Pug template example shows a basic structure for a fake login page. It includes a link to the 'auth.callback' handler to complete the fake login process.
```pug
html
...
a(href=url("auth.callback")) Login
```
--------------------------------
### Bootstrap a Flamingo Application
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Initializes a Flamingo application by registering custom modules and starting the CLI-driven web server. It uses the flamingo.App function to manage the application lifecycle.
```go
package main
import (
"flamingo.me/dingo"
"flamingo.me/flamingo/v3"
)
func main() {
// Bootstrap Flamingo with custom modules
flamingo.App([]dingo.Module{
new(myapp.Module),
new(auth.Module),
})
}
// Run with: go run main.go serve
// Available commands: serve, config, routes, handler, help
```
--------------------------------
### Manage Configuration with YAML and CUE
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Explains how to load and map configuration values into structs using tags. It includes examples of merging YAML files and defining schema constraints using CUE.
```go
func (s *MyService) Inject(cfg *struct {
Endpoint string `inject:"config:myservice.endpoint"`
Timeout int `inject:"config:myservice.timeout"`
Features config.Map `inject:"config:myservice.features"`
}) {
s.endpoint = cfg.Endpoint
s.timeout = cfg.Timeout
var features struct {
Cache bool `json:"cache"`
Logging bool `json:"logging"`
}
cfg.Features.MapInto(&features)
}
```
--------------------------------
### Implement Request Filters (Middleware) in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Provides examples of implementing request filters (middleware) in Go using the Flamingo framework. It demonstrates a LoggingFilter for logging request start and end times, and an AuthFilter that blocks requests if a user is not logged in, redirecting to a login route. Filters are registered using dingo's BindMulti.
```go
package filters
import (
"context"
"net/http"
"time"
"flamingo.me/dingo"
"flamingo.me/flamingo/v3/framework/flamingo"
"flamingo.me/flamingo/v3/framework/web"
)
type LoggingFilter struct {
logger flamingo.Logger
}
func (f *LoggingFilter) Inject(logger flamingo.Logger) {
f.logger = logger
}
// Filter implements web.Filter
func (f *LoggingFilter) Filter(
ctx context.Context,
req *web.Request,
w http.ResponseWriter,
chain *web.FilterChain,
) web.Result {
start := time.Now()
// Pre-processing
f.logger.WithContext(ctx).Info("Request started", req.Request().URL.Path)
// Continue to next filter or controller
result := chain.Next(ctx, req, w)
// Post-processing
duration := time.Since(start)
f.logger.WithContext(ctx).Info("Request completed", duration)
return result
}
// Priority implements web.PrioritizedFilter (higher runs first)
func (f *LoggingFilter) Priority() int {
return 100
}
// AuthFilter example with request blocking
type AuthFilter struct {
responder *web.Responder
}
func (f *AuthFilter) Filter(
ctx context.Context,
req *web.Request,
w http.ResponseWriter,
chain *web.FilterChain,
) web.Result {
if _, ok := req.Session().Load("user"); !ok {
// Block request - return early without calling chain.Next
return f.responder.RouteRedirect("auth.login", nil)
}
return chain.Next(ctx, req, w)
}
// Register filter in module
func (m *Module) Configure(injector *dingo.Injector) {
injector.BindMulti(new(web.Filter)).To(LoggingFilter{})
injector.BindMulti(new(web.Filter)).To(AuthFilter{})
}
```
--------------------------------
### YAML Configuration Syntax Examples
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/config/Readme.md
Demonstrates two equivalent ways to define configuration sections in YAML: using dot notation or nested maps. Also shows how to read values from environment variables, with an optional fallback to a default value.
```yaml
foo:
bar: x
```
```yaml
foo.bar: x
```
```yaml
auth.secret: '%%ENV:KEYCLOAK_SECRET%%'
```
```yaml
auth.secret: '%%ENV:KEYCLOAK_SECRET%%default_value%%'
```
--------------------------------
### Setting up Pact Mock Daemon for Contract Testing
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/4. Others/Faking and Mocking external services.md
Provides instructions for setting up the Pact mock daemon, a crucial step for contract testing with Pact. This involves installing the pact_go library and running the daemon, which listens on port 6666 by default.
```bash
pact-go daemon
```
--------------------------------
### Create Controller Actions with Flamingo
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Demonstrates how to create controller actions in Go that handle HTTP requests and return web.Result responses. It includes examples for basic responses, handling path parameters, form data, and interacting with services.
```go
package controllers
import (
"context"
"net/http"
"strings"
"flamingo.me/flamingo/v3/framework/web"
)
type MyController struct {
responder *web.Responder
service UserService
}
func (c *MyController) Inject(
responder *web.Responder,
service UserService,
) {
c.responder = responder
c.service = service
}
// Index handles the home page
func (c *MyController) Index(ctx context.Context, req *web.Request) web.Result {
return &web.Response{
Status: http.StatusOK,
Body: strings.NewReader("Hello World!"),
}
}
// ShowUser handles user detail page with path parameter
func (c *MyController) ShowUser(ctx context.Context, req *web.Request) web.Result {
userID := req.Params["id"]
user, err := c.service.GetUser(ctx, userID)
if err != nil {
return c.responder.NotFoundWithContext(ctx, err)
}
// Render template with data
return c.responder.Render("user/detail", map[string]interface{}{
"User": user,
})
}
// CreateUser handles POST request with form data
func (c *MyController) CreateUser(ctx context.Context, req *web.Request) web.Result {
name, err := req.Form1("name")
if err != nil {
return c.responder.BadRequestWithContext(ctx, err)
}
email, err := req.Form1("email")
if err != nil {
return c.responder.BadRequestWithContext(ctx, err)
}
user, err := c.service.CreateUser(ctx, name, email)
if err != nil {
return c.responder.ServerErrorWithContext(ctx, err)
}
// Return JSON response
return c.responder.Data(user).Status(http.StatusCreated)
}
```
--------------------------------
### Implement Logging in Flamingo
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/5. Flamingo Production.md
Demonstrates how to inject the flamingo.Logger interface into a struct and use it for various log levels. It also shows how to add context and fields to log entries.
```go
package example
import (
"flamingo.me/flamingo/v3/framework/flamingo"
)
type (
MyStruct struct{
logger flamingo.Logger
}
)
func (s *MyStruct) Inject(logger flamingo.Logger) *MyStruct {
s.logger = logger
return s
}
func (s *MyStruct) SomeFunc() {
s.logger.Debug("This is a debug message")
s.logger.Info("This is an info message")
s.logger.Warn("This is a warning message")
s.logger.Error("This is an error message")
s.logger.Fatal("This is a fatal message")
}
func (s *MyStruct) someFunction(ctx context.Context) {
s.logger.WithField(flamingo.LogKeyCategory, "SomeCategory").Info("This is an info message with context")
s.logger.WithContext(ctx).Info("This is an info message with context")
}
```
--------------------------------
### OAuth Configuration Example
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/oauth/Readme.md
This YAML snippet shows the basic configuration for the OAuth module, including server details, secret, client ID, and an option to disable offline tokens.
```yaml
core:
oauth:
server: flamingo.os.env.OAUTH_SERVER
secret: flamingo.os.env.OAUTH_SECRET
clientid: flamingo.os.env.OAUTH_CLIENTID
disableOfflineToken: true
```
--------------------------------
### Render Dynamic Template Fragments
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/gotemplate/Readme.md
Example of using Go template logic to iterate over data and render specific template fragments dynamically based on conditions.
```html
{{range $i, $p := .Products}}
{{if le $i 0}}
{{template "deep/otherNest/noProducts.html" $p}}
{{end}}
{{template "deep/otherNest/product.html" $p}}
{{end}}
```
--------------------------------
### Load and Cache HTTP Response Data in Go
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/cache/Readme.md
Provides an example of a cache loader function and how to use the HTTPFrontend cache's Get method in Go. It handles caching responses, including semantic errors like 404s, with configurable lifetimes and grace times, and implements single flight for concurrent requests.
```go
loadData := func(ctx context.Context) (*http.Response, *cache.Meta, error) {
r, err := http.DefaultClient.Do(req.WithContext(ctx))
if err != nil {
return nil, nil, err
}
//cache semantic errors for certain time to avoid recalling the same request
if r.StatusCode == http.StatusNotFound {
return r, &cache.Meta{
Lifetime: 5 * time.Minute,
Gracetime: 300 * time.Second,
}, nil
}
//cache semantic errors for certain time to avoid recalling the same request
if r.StatusCode != http.StatusOK {
return r, &cache.Meta{
Lifetime: 10 * time.Second,
Gracetime: 30 * time.Second,
}, nil
}
return r, nil, nil
}
response, err := apiclient.Cache.Get(requestContext, u.String(), loadData)
```
--------------------------------
### Enable Trace Logging via Build Tags
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/5. Flamingo Production.md
Instruction and command to compile the Flamingo application with the tracelog build tag to enable detailed trace-level logging.
```bash
go build -tags tracelog
```
--------------------------------
### Implement Security Middleware for Route Protection in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
This Go code demonstrates how to use Flamingo's security middleware to protect routes. It shows examples of handling routes that require login, specific permissions, or are only accessible to guests. The configuration includes settings for login handlers, redirect strategies, and permission hierarchies.
```go
package mymodule
import (
"flamingo.me/flamingo/v3/core/security/application/middleware"
"flamingo.me/flamingo/v3/framework/web"
)
type routes struct {
controller *MyController
securityMiddleware *middleware.SecurityMiddleware
}
func (r *routes) Routes(registry *web.RouterRegistry) {
// Public routes
registry.Route("/", "home")
registry.HandleAny("home", r.controller.Home)
// Protected: requires login
registry.Route("/dashboard", "dashboard")
registry.HandleGet("dashboard",
r.securityMiddleware.HandleIfLoggedIn(r.controller.Dashboard))
// Protected: requires specific permission
registry.Route("/admin/users", "admin.users")
registry.HandleGet("admin.users",
r.securityMiddleware.HandleIfGranted(r.controller.AdminUsers, "PermissionAdmin"))
// Guest only: redirect if logged in
registry.Route("/register", "register")
registry.HandleGet("register",
r.securityMiddleware.HandleIfLoggedOut(r.controller.Register))
// Deny access if permission present
registry.Route("/basic-features", "basic")
registry.HandleGet("basic",
r.securityMiddleware.HandleIfNotGranted(r.controller.Basic, "PermissionPremium"))
}
// config/config.yml
/*
security:
login:
handler: "auth.login"
redirectStrategy: "referrer" # or "path"
redirectPath: "/dashboard"
authenticatedHomepage:
strategy: "path"
path: "/dashboard"
roles:
permissionHierarchy:
PermissionAdmin:
- PermissionView
- PermissionEdit
PermissionSuperAdmin:
- PermissionAdmin
- PermissionDelete
voters:
strategy: "unanimous" # unanimous|affirmative|consensus
allowIfAllAbstain: false
*/
```
--------------------------------
### Structured Logging with Zap
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Configures and utilizes the Zap logger for structured, context-aware logging. Includes examples of injecting the logger and using trace IDs via context.
```go
type MyService struct {
logger flamingo.Logger
}
func (s *MyService) Inject(logger flamingo.Logger) {
s.logger = logger.WithField("service", "MyService")
}
func (s *MyService) ProcessOrder(ctx context.Context, orderID string) error {
log := s.logger.WithContext(ctx)
log.WithField("orderID", orderID).Info("Processing order")
return nil
}
```
--------------------------------
### Create Flamingo Module and Routes
Source: https://github.com/i-love-flamingo/flamingo/blob/master/Readme.md
Defines a custom module that implements the dingo.Module interface and registers web routes using the RouterRegistry. This example demonstrates binding a root path to a handler that returns a simple HTTP response.
```go
package helloworld
import (
"context"
"net/http"
"strings"
"flamingo.me/dingo"
"flamingo.me/flamingo/v3/framework/web"
)
type Module struct{}
func (*Module) Configure(injector *dingo.Injector) {
web.BindRoutes(injector, new(routes))
}
type routes struct{}
func (*routes) Routes(registry *web.RouterRegistry) {
registry.Route("/", "home")
registry.HandleAny("home", indexHandler)
}
func indexHandler(ctx context.Context, req *web.Request) web.Result {
return &web.Response{
Status: http.StatusOK,
Body: strings.NewReader("Hello World!"),
}
}
```
--------------------------------
### Localization (i18n) Configuration and Usage
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Configures and demonstrates the use of i18n for translating labels and formatting dates, numbers, and currencies based on locale settings. It includes configuration examples for locales, translations, and template usage.
```go
// config/config.yml
/*
locale:
locale: "en-GB"
fallbackLocales:
- "en-US"
translationFiles:
- "translations/en-gb.all.yaml"
accounting:
default:
thousand: ","
decimal: "."
format: "%s %v"
formatZero: "%s -.-"
GBP:
format: "%s%v"
numbers:
thousand: ","
decimal: "."
precision: 2
date:
dateFormat: "02 Jan 2006"
timeFormat: "15:04:05"
dateTimeFormat: "02 Jan 2006 15:04:05"
location: "Europe/London"
*/
// translations/en-gb.all.yaml
/*
- id: "welcome.message"
translation: "Welcome, {{.Name}}!"
- id: "items.count"
translation:
one: "{{.Count}} item"
other: "{{.Count}} items"
*/
// Template usage (gotemplate/pug):
/*
{{ __("welcome.message").setTranslationArguments (dict "Name" .User.Name) }}
{{ __("missing.key").setDefaultLabel "Default Text" }}
{{ __("items.count").setCount .ItemCount }}
{{ __("greeting").setLocale "de-DE" }}
{{dateTimeFormatFromIso "2024-01-15T10:30:00Z" | .formatDate }}
{{dateTimeFormat .CreatedAt | .formatToLocalDate }}
{{ priceFormat 99.99 "£" }}
{{ priceFormatLong 1299.50 "$" "USD" }}
{{ numberFormat 12345.67 }}
{{ numberFormat 12345.6789 4 }}
*/
```
--------------------------------
### Containerize Flamingo Application with Docker
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/5. Flamingo Production.md
A multi-stage Dockerfile for building and running a Flamingo Go application. It compiles the binary in a builder stage and creates a minimal scratch image for production deployment.
```dockerfile
FROM golang:alpine AS builder
RUN apk update && apk add --no-cache ca-certificates tzdata git && update-ca-certificates
COPY . /app
RUN cd /app && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
FROM scratch
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]
CMD ["serve"]
```
--------------------------------
### Initialize Flamingo Project
Source: https://github.com/i-love-flamingo/flamingo/blob/master/Readme.md
Commands to set up a new Go project directory and initialize the Go module system for a Flamingo application.
```bash
mkdir helloworld
cd helloworld
go mod init helloworld
```
--------------------------------
### GET /status/ping
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/3. Core Modules/Heathcheck.md
Checks if the application is up and running. Returns 'ok' if the application is responsive.
```APIDOC
## GET /status/ping
### Description
Checks if the application is up and running. This is a simple ping endpoint to verify basic connectivity.
### Method
GET
### Endpoint
/status/ping
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
None
### Response
#### Success Response (200)
- **message** (string) - Indicates the application is responsive, typically 'ok'.
#### Response Example
```json
{
"message": "ok"
}
```
```
--------------------------------
### Define Translation Files
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/locale/Readme.md
Example structure for JSON-based translation files used by the localization module.
```json
[
{
"id": "attribute.clothingSize",
"translation": "Size"
},
{
"id": "error404.headline",
"translation": "Page not found!"
}
]
```
--------------------------------
### Define Configuration Syntax and Environment Variables
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/2. Framework Modules/Configuration.md
Demonstrates how to define configuration keys using dot notation or YAML maps, and how to inject environment variables with optional default values.
```yaml
foo:
bar: x
# Equivalent to:
foo.bar: x
# Environment variable with fallback:
auth.secret: '%%ENV:KEYCLOAK_SECRET%%default_value%%'
```
--------------------------------
### GET /status/healthcheck
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/3. Core Modules/Heathcheck.md
Performs a comprehensive health check of the application, verifying various components and services.
```APIDOC
## GET /status/healthcheck
### Description
Performs a comprehensive health check of the application. This endpoint verifies the status of different components and services configured for health checking.
### Method
GET
### Endpoint
/status/healthcheck
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
None
### Response
#### Success Response (200)
- **status** (string) - The overall health status of the application (e.g., 'healthy', 'degraded', 'unhealthy').
- **checks** (object) - A detailed breakdown of individual health checks performed.
- **checkName** (object) - Status and details for a specific check.
- **status** (string) - The status of the individual check (e.g., 'pass', 'fail').
- **message** (string) - A descriptive message about the check's result.
#### Response Example
```json
{
"status": "healthy",
"checks": {
"session": {
"status": "pass",
"message": "Session service is available."
},
"authentication": {
"status": "pass",
"message": "Authentication service is functioning correctly."
}
}
}
```
```
--------------------------------
### Register Custom Role Provider
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/security/Readme.md
Example of binding a custom role provider into the Flamingo dependency injection container.
```go
func (m *Module) Configure(injector *dingo.Injector) {
injector.BindMulti(new(role.Provider))).To(provider.CustomProvider{})
}
```
--------------------------------
### Register Custom Security Voter
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/security/Readme.md
Example of binding a custom security voter into the Flamingo dependency injection container.
```go
func (m *Module) Configure(injector *dingo.Injector) {
injector.BindMulti(new(voter.SecurityVoter))).To(voter.CustomVoter{})
}
```
--------------------------------
### Create Fake Login Template
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/3. Core Modules/OAuth.md
A Pug template example for a fake login page that redirects to the authentication callback handler.
```pug
html
a(href=url("auth.callback")) Login
```
--------------------------------
### Load Configurations via Environment Variables and Flags
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/2. Framework Modules/Configuration.md
Shows how to load context-specific configuration files and external files, as well as overriding values directly via command-line flags.
```bash
# Load context-based config
CONTEXT="dev:testdata" go run project.go serve
# Load external config files
CONTEXTFILE="../../myCfg.yml:/var/flamingo/cfg/main.yml" go run project.go serve
# Override via flags
go run project.go serve --flamingo-config "auth.secret: mySecret"
```
--------------------------------
### Configure Custom Logger Implementation
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/5. Flamingo Production.md
Shows how to override the default logger implementation in a Flamingo application using the WithCustomLogger application option.
```go
package main
import (
"flamingo.me/flamingo/v3"
)
func main() {
flamingo.App([]dingo.Module{
// your modules
}, flamingo.WithCustomLogger(new(MyLogModule)))
}
```
--------------------------------
### Configure Application Areas and Routing in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Sets up the main application entry point in Go using the Flamingo framework. It configures modules and defines child areas for routing, enabling multi-tenancy and API versioning. Dependencies include the flamingo.me/dingo and flamingo.me/flamingo/v3 packages.
```go
package main
import (
"flamingo.me/dingo"
"flamingo.me/flamingo/v3"
"flamingo.me/flamingo/v3/framework/prefixrouter"
)
func main() {
flamingo.App([]dingo.Module{
new(prefixrouter.Module),
// ...other modules
}, flamingo.ChildAreas(
flamingo.NewArea("de", "/de", nil),
flamingo.NewArea("en", "/en", nil),
flamingo.NewArea("api-v1", "/api/v1", nil),
flamingo.NewArea("api-v2", "/api/v2", nil),
))
}
```
--------------------------------
### Loading Configuration with Context and Environment Variables
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/config/Readme.md
Illustrates how to load additional configuration files based on the CONTEXT environment variable, supporting single and multiple contexts. It also shows how to load configuration files from outside the default config directory using the CONTEXTFILE environment variable.
```bash
CONTEXT="dev" go run project.go serve
```
```bash
CONTEXT="dev:testdata" go run project.go serve
```
```bash
CONTEXTFILE="../../myCfg.yml:/var/flamingo/cfg/main.yml:/var/flamingo/cfg/additional.cue" go run project.go serve
```
--------------------------------
### Inject Configuration via Dingo
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/2. Framework Modules/Configuration.md
Illustrates how to inject configuration values into a module using Dingo tags and how to marshal nested maps into Go structs.
```go
func (m *Module) Inject(
cfg *struct {
CompleteConfig config.Map `inject:"config:mymodule"`
Title string `inject:"config:mymodule.title"`
Amount int `inject:"config:mymodule.amount"`
Flag bool `inject:"config:mymodule.flag"`
},
) *Module {
if cfg != nil {
m.title = cfg.Title
m.amount = cfg.Amount
m.flag = cfg.Flag
m.cfg = cfg.CompleteConfig
}
return m
}
// Marshal nested config to struct
err := m.MarshalTo(&result)
```
--------------------------------
### Configure OIDC Authentication with Keycloak in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
This Go code demonstrates how to configure OpenID Connect (OIDC) authentication with Keycloak using a YAML configuration file. It shows how to define client ID, secret, endpoint, and scopes. The controller code illustrates fetching user identities and redirecting to login if not authenticated.
```go
// config/config.yml
/*
core:
auth:
web:
broker:
- broker: "keycloak"
typ: "oidc"
clientID: "my-app"
clientSecret: "${OIDC_SECRET}"
endpoint: "https://keycloak.example.com/realms/myrealm"
scopes:
- "email"
- "profile"
enableOfflineToken: true
claims:
idToken:
name: "name"
email: "email"
*/
package controllers
import (
"context"
"flamingo.me/flamingo/v3/core/auth"
"flamingo.me/flamingo/v3/framework/web"
)
type AuthController struct {
webIdentityService *auth.WebIdentityService
responder *web.Responder
}
func (c *AuthController) Inject(
service *auth.WebIdentityService,
responder *web.Responder,
) {
c.webIdentityService = service
c.responder = responder
}
// Profile shows authenticated user info
func (c *AuthController) Profile(ctx context.Context, req *web.Request) web.Result {
// Get all identities
identities := c.webIdentityService.IdentifyAll(ctx, req)
if len(identities) == 0 {
return c.responder.RouteRedirect("auth.login", nil)
}
identity := identities[0]
return c.responder.Render("profile", map[string]interface{}{
"Subject": identity.Subject(),
"Broker": identity.Broker(),
})
}
// IdentifyByBroker gets identity from specific broker
func (c *AuthController) IdentifyByBroker(ctx context.Context, req *web.Request) web.Result {
identity, err := c.webIdentityService.Identify(ctx, req, "keycloak")
if err != nil {
return c.responder.Forbidden(err)
}
return c.responder.Data(map[string]string{
"subject": identity.Subject(),
})
}
```
--------------------------------
### Configuring Routes via YAML
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/web/docs/ReadmeRouter.md
Shows how to define application routes declaratively using a routes.yml configuration file, mapping paths to specific controllers.
```yaml
- path: /
name: index
controller: flamingo.render(tpl="index")
- path: /anotherPath
controller: flamingo.render(tpl="index")
- path: /redirect
controller: flamingo.redirect(to="index")
```
--------------------------------
### Register Custom Module in Main
Source: https://github.com/i-love-flamingo/flamingo/blob/master/Readme.md
Updates the main application entry point to include and initialize the custom helloworld module.
```go
package main
import (
"flamingo.me/dingo"
"flamingo.me/flamingo/v3"
"helloworld/helloworld"
)
func main() {
flamingo.App([]dingo.Module{
new(helloworld.Module),
})
}
```
--------------------------------
### Fire Event using EventRouter in Go
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/flamingo/ReadmeEvents.md
Shows how to dispatch an event using the EventRouter within a controller. It includes dependency injection for EventRouter and Responder, and the dispatching logic in the Get method.
```go
type (
IndexController struct {
responder *web.Responder
eventRouter flamingo.EventRouter
}
MyEvent struct {
Data string
}
)
// Inject dependencies
func (controller *IndexController) Inject(
eventRouter flamingo.EventRouter,
responder *web.Responder,
) *IndexController {
controller.responder = responder
controller.eventRouter = eventRouter
return controller
}
// Get the data
func (controller *IndexController) Get(ctx context.Context, r *web.Request) web.Result {
controller.eventRouter.Dispatch(ctx, &MyEvent{Data: "Hello"})
return controller.responder.TODO()
}
```
--------------------------------
### Create and Register Data Controllers in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Defines a data controller in Go for fetching dynamic data to be used in templates. It demonstrates dependency injection for a product service and how to register the controller with the web router. The `FeaturedProducts` action fetches products based on a limit parameter.
```go
package controllers
import (
"context"
"strconv"
"flamingo.me/flamingo/v3/framework/web"
)
type ProductService interface {
GetFeatured(ctx context.Context, limit int) (interface{}, error)
}
type DataController struct {
productService ProductService
}
func (c *DataController) Inject(service ProductService) {
c.productService = service
}
// Data action returns data for templates
func (c *DataController) FeaturedProducts(
ctx context.Context,
req *web.Request,
params web.RequestParams,
) interface{} {
limit := 4
if l, ok := params["limit"]; ok {
limit, _ = strconv.Atoi(l)
}
products, _ := c.productService.GetFeatured(ctx, limit)
return products
}
// Register data controller
type routes struct {
dataController *DataController
}
func (r *routes) Routes(registry *web.RouterRegistry) {
registry.HandleData("product.featured", r.dataController.FeaturedProducts)
}
/*
// Template usage
{{
$featured := data "product.featured" (dict "limit" 6)
}}
{{range $featured}}
{{.Name}}
{{end}}
*/
```
--------------------------------
### Implement Dependency Injection with Dingo
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Shows how to use Dingo for constructor and field injection, including binding interfaces to implementations and using provider functions. It covers both service-level injection and module-level configuration.
```go
func (m *Module) Configure(injector *dingo.Injector) {
injector.Bind(new(UserRepository)).To(MySQLUserRepository{})
injector.Bind(new(CacheBackend)).AnnotatedWith("primary").To(RedisCache{})
injector.Bind(new(ConnectionPool)).In(dingo.Singleton)
injector.Bind(new(HTTPClient)).ToProvider(func(cfg *HTTPConfig) *HTTPClient {
return NewHTTPClient(cfg.Timeout, cfg.MaxRetries)
})
}
```
--------------------------------
### Initialize Flamingo Application with Modules and Config Areas
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/7. Flamingo Bootstrap.md
Demonstrates the standard entry point for a Flamingo application using flamingo.App. It registers framework and commerce modules while defining child configuration areas for multi-locale support.
```go
func main() {
flamingo.App([]dingo.Module{
//flamingo framework modules:
new(requestlogger.Module), // requestlogger show request logs
new(prefixrouter.Module),
new(pugtemplate.Module),
new(locale.Module),
new(opentelemetry.Module),
new(auth.Module),
//flamingo-commerce modules
new(product.Module),
new(price.Module),
new(category.Module),
new(cart.Module),
new(customer.Module),
new(checkout.Module),
//flamingo-commerce-adpater-standalone
new(csvcommerce.ProductClientModule),
new(csvcommerce.SearchClientModule),
}, flamingo.ChildAreas(
config.NewArea("de", nil),
config.NewArea("en", nil),
))
}
```
--------------------------------
### Register Custom Health Check for Session Backend
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/2. Framework Modules/Flamingo_Session.md
Example of binding a custom health check status to the session key using the Dingo injector. This ensures the session backend's health is monitored by the system.
```go
injector.BindMap(new(healthcheck.Status), "session").To(new(db.Health))
```
--------------------------------
### Generate URLs with Reverse Routing
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Demonstrates how to generate relative and absolute URLs from route names and parameters using the ReverseRouter interface. It also provides examples of how to invoke these routes within Go controllers and Go templates.
```go
func (c *NavigationController) GenerateURLs(ctx context.Context, req *web.Request) web.Result {
relativeURL, err := c.router.Relative("user.show", map[string]string{
"id": "123",
})
absoluteURL, err := c.router.Absolute(req, "product.detail", map[string]string{
"slug": "awesome-product",
})
if err != nil {
return c.responder.ServerError(err)
}
return c.responder.Data(map[string]string{
"relative": relativeURL.String(),
"absolute": absoluteURL.String(),
})
}
```
--------------------------------
### Go Templates with Layouts, Partials, and Functions
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Utilizes the built-in Go template engine for web page rendering, supporting layouts, partials, and custom template functions. Configuration specifies template directories, and controller usage demonstrates rendering dynamic content.
```go
// templates/layouts/base.html
/*
{{template "title" .}}{{template "header" .}}{{template "content" .}}
*/
// templates/pages/home.html
/*
{{template "layouts/base.html" .}}
{{define "title"}}Home - {{.SiteName}}{{end}}
{{define "header"}}
{{end}}
{{define "content"}}
*/
// config/config.yml
/*
gotemplates:
engine:
templates:
basepath: "templates"
layout:
dir: "layouts"
*/
// Controller usage
func (c *Controller) Home(ctx context.Context, req *web.Request) web.Result {
return c.responder.Render("pages/home", map[string]interface{}{
"SiteName": "My Shop",
"Products": products,
"User": req.Session().Try("user"),
})
}
```
--------------------------------
### Use go:generate for reproducible code generation
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/8. Coding Conventions.md
Shows the recommended syntax for using go:generate directives, emphasizing the use of 'go tool' to ensure consistent tool versions across environments.
```go
//go:generate go tool mockery
```
--------------------------------
### Run Go unit tests for a specific package
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/8. Coding Conventions.md
Demonstrates the command-line usage of the standard Go testing tool to execute tests within a specific Flamingo framework package.
```bash
go test -v flamingo.me/flamingo/v3/framework/config
```
--------------------------------
### Manage Sessions and Flash Messages in Go
Source: https://context7.com/i-love-flamingo/flamingo/llms.txt
Illustrates how to manage user sessions and flash messages using the Flamingo framework's web.Request.Session() object in Go. It covers storing and retrieving data, deleting session keys, accessing the session ID hash, and adding/retrieving flash messages that are displayed once. Session configuration is shown via a YAML example.
```go
package controllers
import (
"context"
"flamingo.me/flamingo/v3/framework/web"
)
func SessionExample(ctx context.Context, req *web.Request) web.Result {
session := req.Session()
// Store data in session
session.Store("user_id", "12345")
session.Store("cart", map[string]int{"product1": 2})
// Load data from session
if userID, ok := session.Load("user_id"); ok {
_ = userID.(string)
}
// Try to load (returns nil if not found)
userData := session.Try("user_data")
if userData != nil {
// process user data
}
// Delete session key
session.Delete("temp_data")
// Get session ID (hashed for logging)
sessionHash := session.IDHash()
// Flash messages (shown once then removed)
session.AddFlash("Operation successful!", "success")
session.AddFlash("Please review your input", "warning")
// Retrieve flash messages
successFlashes := session.Flashes("success")
for _, msg := range successFlashes {
_ = msg.(string)
}
return &web.Response{Status: 200}
}
// Configuration in config.yml:
// flamingo:
// session:
// name: "mysession"
// backend: "redis" # or "file", "memory"
// redis:
// host: "localhost:6379"
```
--------------------------------
### Registering Fake Service Implementation in Flamingo
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/4. Others/Faking and Mocking external services.md
Demonstrates how to register a fake service implementation within the Flamingo module.go file. This allows for internal faking of external API calls, enabling independent local testing.
```go
injector.Override(new(productdomain.BrandService), "").To(product.FakeService{})
```
--------------------------------
### Registering Routes in Flamingo Modules
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/web/docs/ReadmeRouter.md
Demonstrates how to bind a RoutesModule using Dingo dependency injection and implement the Routes interface to register URL paths and handlers.
```go
// Configure DI
func (m *) Configure(injector *dingo.Injector) {
web.BindRoutes(injector, new(routes))
}
// RoutesModule defines a router RoutesModule, which is able to register routes
RoutesModule interface {
Routes(registry *RouterRegistry)
}
func (r *routes) Routes(registry *router.Registry) {
registry.Route("/hello", "hello")
registry.HandleGet("hello", r.helloController.Get)
}
```
--------------------------------
### Injecting and Using HTTPFrontend Cache in Go
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/3. Core Modules/Cache.md
Demonstrates how to inject an HTTPFrontend cache using dependency injection and then use it to cache API responses. The cache handles cache hits, grace periods, and ensures single flight requests when the cache is empty.
```go
type MyApiClient struct {
Cache *cache.HTTPFrontend `inject:"myservice"
}
injector.Bind((*cache.HTTPFrontend)(nil)).AnnotatedWith("myservice").In(dingo.Singleton)
loadData := func(ctx context.Context) (*http.Response, *cache.Meta, error) {
r, err := http.DefaultClient.Do(req.WithContext(ctx))
if err != nil {
return nil, nil, err
}
//cache semantic errors for certain time to avoid recalling the same request
if r.StatusCode == http.StatusNotFound {
return r, &cache.Meta{
Lifetime: 5 * time.Minute,
Gracetime: 300 * time.Second,
}, nil
}
//cache semantic errors for certain time to avoid recalling the same request
if r.StatusCode != http.StatusOK {
return r, &cache.Meta{
Lifetime: 10 * time.Second,
Gracetime: 30 * time.Second,
}, nil
}
return r, nil, nil
}
response, err := apiclient.Cache.Get(requestContext, u.String(), loadData)
```
--------------------------------
### Project Root File Structure
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/1. Flamingo Basics/2. Flamingo Project Structure.md
Illustrates the top-level files and directories in a typical Flamingo project. This includes the main entry point (main.go), configuration files, source code directories, and frontend assets.
```tree
projectName (Project Root)
│ main.go (The entry for your project)
│ README.md
│ Dockerfile
│ Makefile
│ (Jenkinsfile or other CI config)
│ go.mod
│ go.sum
│
└───config (Your project configuration)
│ └───config.yml (Main project config)
│ └───config_dev.yml (additional configs - e.g. this one is loaded for CONTEXT dev)
│ └───routes.yml (Routing config)
│ └───SUBFOLDER (Optional additional configuration context)
│ └───config.yml (Additional config for this context)
│
└───src (Project specific modules live here)
│ └───myModule (a module - see module structure below)
│
└───frontend (Frontend templates - if "flamingo-carotene" is used)
│ └───src (main frontend source / structure by atomic design)
│ │ └───atom (see flamingo-carotene)
│ │ └───molecule
│ │ └───...
│ └───dist (not part of VCS - will have frontend build result)
```
--------------------------------
### Bootstrap Flamingo Application
Source: https://github.com/i-love-flamingo/flamingo/blob/master/Readme.md
The entry point for a Flamingo application using the flamingo.App function to register modules.
```go
package main
import (
"flamingo.me/dingo"
"flamingo.me/flamingo/v3"
)
func main() {
flamingo.App([]dingo.Module{
})
}
```
--------------------------------
### Extend Role Providers by Implementing Provider Interface (Go)
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/3. Core Modules/Security.md
Explains how to extend the role provider functionality by implementing the Provider interface. This allows for custom logic to fetch roles granted to a user within a session. The custom provider is then registered with the dependency injection system.
```go
func (m *Module) Configure(injector *dingo.Injector) {
injector.BindMulti(new(role.Provider))).To(provider.CustomProvider{})
}
type Provider interface {
All(context.Context, *sessions.Session) []domain.Role
}
```
--------------------------------
### Implement Security Middleware in Routes
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/security/Readme.md
Demonstrates how to inject security middleware into a router registry to protect routes based on authentication status or specific permissions.
```go
type routes struct {
someController *controller.SomeController
securityMiddleware *middleware.SecurityMiddleware
}
func (r *routes) Routes(registry *router.Registry) {
registry.HandleGet("register", r.securityMiddleware.HandleIfLoggedOut(r.someController.Register))
registry.HandleGet("my.account", r.securityMiddleware.HandleIfLoggedIn(r.someController.MyAccount))
registry.HandleGet("users.list", r.securityMiddleware.HandleIfGranted(r.someController.Users, "PermissionAdmin"))
registry.HandleGet("users.list", r.securityMiddleware.HandleIfNotGranted(r.someController.Users, "PermissionSuperAdmin"))
}
```
--------------------------------
### Implement Web Responses with Flamingo Responder
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/web/docs/ReadmeResponse.md
Demonstrates how to inject the web.Responder dependency and utilize its methods to return rendered templates, JSON data, or perform URL and route redirects within a controller.
```go
type (
MyController struct {
responder *web.Responder
}
)
// Inject dependencies
func (mc *MyController) Inject(
responder *web.Responder
) {
cc.responder = responder
}
func (mc *MyController) MyAction(ctx context.Context, r *web.Request) web.Result {
// Render response to render a template and optional pass template data. It is using the reigstered template enginge.
mc.responder.Render("template",data)
//Data response - e.g. to return JSON
mc.responder.Data(data)
//Redirect to the given URL
mc.responder.URLRedirect(url)
//Redirect to a Flamingo handler (see Routing)
mc.responder.RouteRedirect("flamingo.handler")
}
```
--------------------------------
### Define Template with Layout Inheritance
Source: https://github.com/i-love-flamingo/flamingo/blob/master/core/gotemplate/Readme.md
Shows how to structure an HTML template to use a base layout. It uses the template action to include the layout and define blocks for content injection.
```html
{{template "layouts/base.html" .}}
{{define "title"}}
Hello World
{{end}}
{{define "content"}}
Huzzah! It works!
This is an example text.
{{end}}
```
--------------------------------
### Executing Flamingo Commands
Source: https://github.com/i-love-flamingo/flamingo/blob/master/docs/2. Framework Modules/Flamingo_Commands.md
Shows the standard command-line syntax for executing custom commands within a Flamingo project environment.
```bash
go run main.go myCommand
```
--------------------------------
### Mapping Handlers to Actions
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/web/docs/ReadmeRouter.md
Illustrates how to map a single handler identifier to multiple HTTP methods (GET/POST) within the router registry.
```go
registry.HandleGet("hello", r.helloController.Get)
registry.HandlePost("hello", r.helloController.Get)
```
--------------------------------
### Injecting Configuration Values in Go
Source: https://github.com/i-love-flamingo/flamingo/blob/master/framework/config/Readme.md
Demonstrates how to inject configuration values into a Go struct using Dingo's `inject` tag. It shows how to request specific configuration keys (e.g., `mymodule.title`) or entire configuration maps (`config:mymodule`).
```go
// Inject dependencies
func (m *Module) Inject(
cfg *struct {
CompleteConfig config.Map `inject:"config:mymodule"`
Title string `inject:"config:mymodule.title"`
Amount int `inject:"config:mymodule.amount"`
Flag bool `inject:"config:mymodule.flag"`
},
) *Module {
if cfg != nil {
m.title = cfg.Title
m.amount = cfg.Amount
m.flag = cfg.Flag
m.cfg = cfg.CompleteConfig
}
return m
}
```