Instradamento
Il ruolo del percorso (route) nel framework Go Fiber è quello di associare diversi URL a funzioni di gestione, al fine di supportare l'elaborazione delle richieste HTTP. Serve come punto di ingresso per tutte le richieste del framework web.
Gestori dei percorsi (Funzioni)
Registra i percorsi associati a metodi HTTP specifici.
Nota: In alcuni framework, i gestori dei percorsi sono chiamati controller, che generalmente hanno lo stesso significato: determinare quale funzione (metodo) gestire la richiesta HTTP in ingresso.
Firma della funzione:
// Metodi HTTP
func (app *App) Get(path string, handlers ...Handler) Router
func (app *App) Head(path string, handlers ...Handler) Router
func (app *App) Post(path string, handlers ...Handler) Router
func (app *App) Put(path string, handlers ...Handler) Router
func (app *App) Delete(path string, handlers ...Handler) Router
func (app *App) Connect(path string, handlers ...Handler) Router
func (app *App) Options(path string, handlers ...Handler) Router
func (app *App) Trace(path string, handlers ...Handler) Router
func (app *App) Patch(path string, handlers ...Handler) Router
// Add ti permette di specificare i metodi come valori
func (app *App) Add(method, path string, handlers ...Handler) Router
// Registra il percorso su tutti i metodi HTTP
// Simile a app.Use ma non associa un prefisso
func (app *App) All(path string, handlers ...Handler) Router
Esempio:
// Semplice gestore GET
app.Get("/api/list", func(c *fiber.Ctx) error {
return c.SendString("Questa è una richiesta GET!")
})
// Semplice gestore POST
app.Post("/api/register", func(c *fiber.Ctx) error {
return c.SendString("Questa è una richiesta POST!")
})
Use viene utilizzato per caricare middleware e intercettori di URL del prefisso. Questi percorsi corrispondono solo all'inizio di ciascun percorso, ad esempio, /john
corrisponderà a /john/doe
, /johnnnnn
, e così via.
Firma della funzione middleware personalizzata:
func (app *App) Use(args ...interface{}) Router
Esempio:
// Corrispondi a qualsiasi richiesta
app.Use(func(c *fiber.Ctx) error {
return c.Next()
})
// Corrispondi alle richieste che iniziano con /api
app.Use("/api", func(c *fiber.Ctx) error {
return c.Next()
})
// Corrispondi alle richieste che iniziano con /api o /home (supporta più prefissi)
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
return c.Next()
})
// Aggiungi più gestori
app.Use("/api", func(c *fiber.Ctx) error {
c.Set("X-Custom-Header", random.String(32))
return c.Next()
}, func(c *fiber.Ctx) error {
return c.Next()
})
Percorso
Il percorso del percorso, insieme al metodo della richiesta, definisce i endpoint a cui è possibile accedere. Il percorso del percorso può essere una stringa o un modello di stringa.
Esempi di percorsi basati su stringhe
// Questo percorso del percorso corrisponderà alle richieste al percorso radice, "/":
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Percorso radice")
})
// Questo percorso del percorso corrisponderà alle richieste a "/about":
app.Get("/about", func(c *fiber.Ctx) error {
return c.SendString("Informazioni")
})
// Questo percorso del percorso corrisponderà alle richieste a "/random.txt":
app.Get("/random.txt", func(c *fiber.Ctx) error {
return c.SendString("Random.txt")
Come nel framework expressJs, l'ordine in cui vengono dichiarati i percorsi è importante. Quando viene ricevuta una richiesta, i percorsi vengono controllati nell'ordine in cui sono dichiarati.
Si prega di notare: Assicurarsi che i percorsi con parametri variabili siano scritti dopo i percorsi contenenti parti fisse per evitare che queste parti variabili vengano corrisposte erroneamente, il che potrebbe portare a un comportamento inaspettato.
Parametri di percorso
I parametri di percorso sono elementi dinamici in un percorso e possono essere segmenti nome o senza nome. Questi segmenti vengono utilizzati per catturare i valori in posizioni specifiche nell'URL. È possibile utilizzare la funzione Params per recuperare questi valori, dove il parametro della funzione è il nome del parametro di percorso nel percorso o, per i parametri senza nome, sono i caratteri (*, +) e il loro conteggio.
Il carattere jolly (*) o il segno più (+) rappresentano parametri avidi.
I percorsi forniscono anche la possibilità di utilizzare parametri opzionali. Per i parametri nominati, questi parametri sono seguiti da un punto interrogativo (?), mentre il segno più non è opzionale e è possibile utilizzare caratteri jolly per rappresentare un intervallo di parametri facoltativi e avidi.
Esempio di definizione di un percorso con parametri di percorso
// Parametri
app.Get("/utente/:nome/libri/:titolo", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s\n", c.Params("nome"))
fmt.Fprintf(c, "%s\n", c.Params("titolo"))
return nil
})
// Più - avido - non facoltativo
app.Get("/utente/+", func(c *fiber.Ctx) error {
return c.SendString(c.Params("+"))
})
// Parametro opzionale
app.Get("/utente/:nome?", func(c *fiber.Ctx) error {
return c.SendString(c.Params("nome"))
})
// Jolly - avido - facoltativo
app.Get("/utente/*", func(c *fiber.Ctx) error {
return c.SendString(c.Params("*"))
})
// Questo percorso corrisponderà alla richiesta "/v1/qualche/risorsa/nome:verboPersonalizzato" perché i caratteri del parametro sono stati elusi
app.Get(`/v1/qualche/risorsa/nome\:verboPersonalizzato`, func(c *fiber.Ctx) error {
return c.SendString("Ciao, Community")
})
Poiché i trattini (-) e i punti (.) sono interpretati letteralmente, possono essere utilizzati insieme ai parametri di percorso per scopi utili.
Tutti i caratteri speciali dei parametri possono anche essere elusi utilizzando
\
e i loro valori verranno ignorati, quindi se si desidera utilizzarli nel percorso. È consigliabile utilizzare apici inversi ``, poiché nella documentazione delle espressioni regolari Go vengono sempre utilizzati per garantire l'assenza di ambiguità e i caratteri di escape non influenzano involontariamente il modello di espressione regolare.
// http://localhost:3000/pianeta/prunus.persica
app.Get("/pianeta/:genere.:specie", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s.%s\n", c.Params("genere"), c.Params("specie"))
return nil // prunus.persica
// http://localhost:3000/voli/LAX-SFO
app.Get("/voli/:da-:a", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s-%s\n", c.Params("da"), c.Params("a"))
return nil // LAX-SFO
})
Il nostro routing intelligente riconosce che i caratteri del parametro introdotti in questo caso dovrebbero far parte del percorso della richiesta e può gestirlo come tale.
// http://localhost:3000/negozio/prodotto/colore:blu/dimensione:xs
app.Get("/negozio/prodotto/colore::colore/dimensione::dimensione", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s:%s\n", c.Params("colore"), c.Params("dimensione"))
return nil // blu:xs
})
Inoltre, i percorsi possono utilizzare parametri multipli e caratteri di parametro senza nome multipli consecutivamente, come caratteri jolly o più, espandendo notevolmente le possibilità per gli utenti nei percorsi.
// GET /@v1
// Params: "segno" -> "@", "param" -> "v1"
app.Get("/:segno:param", handler)
// GET /api-v1
// Params: "nome" -> "v1"
app.Get("/api-:nome", handler)
// GET /cliente/v1/carrello/proxy
// Params: "*1" -> "cliente/", "*2" -> "/carrello"
app.Get("/*v1*/proxy", handler)
// GET /v1/marchio/4/negozio/blu/xs
// Params: "*1" -> "marchio/4", "*2" -> "blu/xs"
app.Get("/v1/*/negozio/*", handler)
Abbiamo già adattato il routing al routing di Express, ma non supporta ancora le espressioni regolari perché sono relativamente lente.
Vincoli
Quando c'è una corrispondenza con l'URL in ingresso e il percorso dell'URL è diviso in valori di percorso attraverso parametri, i vincoli verranno eseguiti. Questa funzionalità è stata introdotta nella versione v2.37.0
ed è stata ispirata da .NET Core.
I vincoli non sono per la convalida dei parametri. Se il vincolo non è valido per il valore del parametro, Fiber restituirà un gestore 404.
Vincolo | Esempio | Corrispondenza dell'esempio |
---|---|---|
int | :id |
123456789, -123456789 |
bool | :active |
true, false |
guid | :id |
CD2C1638-1638-72D5-1638-DEADBEEF1638 |
float | :weight |
1.234, -1,001.01e8 |
minLen(valore) | :username<minLen(4)> | test (almeno 4 caratteri) |
maxLen(valore) | :filename<maxLen(8)> | MyFile (fino a 8 caratteri) |
len(lunghezza) | :filename<len(12)> | somefile.txt (12 caratteri) |
min(valore) | :age<min(18)> | 19 (il valore intero deve essere almeno 18) |
max(valore) | :age<max(120)> | 91 (il valore intero non può superare 120) |
range(min,max) | :age<range(18,120)> | 91 (il valore intero deve essere almeno 18 ma non può superare 120) |
alpha | :name |
Rick (la stringa deve consistere in uno o più caratteri alfabetici, senza distinzione tra maiuscole e minuscole, a-z) |
datetime | :dob<datetime(2006\\-01\\-02)> | 2005-11-01 |
regex(espressione) | :date<regex(\d{4}-\d{2}-\d{2})> | 2022-08-27 (deve corrispondere all'espressione regolare) |
Esempi
- Singolo vincolo
- Vincoli multipli
- Vincolo di espressione regolare
app.Get("/:test", func(c *fiber.Ctx) error {
return c.SendString(c.Params("test"))
})
// curl -X GET http://localhost:3000/12 // 12
// curl -X GET http://localhost:3000/1 // Impossibile trovare GET /1
Puoi utilizzare `;` per aggiungere vincoli multipli.
app.Get("/:test", func(c *fiber.Ctx) error { return c.SendString(c.Params("test")) })
// curl -X GET http://localhost:3000/120000 // Impossibile trovare GET /120000
// curl -X GET http://localhost:3000/1 // Impossibile trovare GET /1
// curl -X GET http://localhost:3000/250 // 250
Fiber precompila le query delle espressioni regolari durante la registrazione dei percorsi, quindi non c'è alcun impatto sulle prestazioni per i vincoli di espressione regolare.
```go
app.Get(`/:date`, func(c *fiber.Ctx) error {
return c.SendString(c.Params("date"))
})
// curl -X GET http://localhost:3000/125 // Impossibile trovare GET /125
// curl -X GET http://localhost:3000/test // Impossibile trovare GET /test
// curl -X GET http://localhost:3000/2022-08-27 // 2022-08-27
> Quando si utilizzano i vincoli di data e ora (`*`,`+`,`?`,`:`,`/`,``,``,`>`,`<`,`;`,`(`,`)`), utilizzare `\\` prima di utilizzare caratteri speciali nel percorso per evitare interpretazioni errate.
**Esempio di parametro opzionale**
È anche possibile aggiungere vincoli ai parametri opzionali.
```go
app.Get("/:test?", func(c *fiber.Ctx) error {
return c.SendString(c.Params("test"))
})
// curl -X GET http://localhost:3000/42
// 42
// curl -X GET http://localhost:3000/
//
// curl -X GET http://localhost:3000/7.0
// Impossibile trovare GET /7.0
Middleware
Le funzioni progettate per manipolare richieste o risposte sono chiamate funzioni middleware. Next
è una funzione di routing di Fiber che, quando chiamata, esegue la funzione next
che corrisponde all'attuale percorso.
Esempio di funzione middleware
app.Use(func(c *fiber.Ctx) error {
// Imposta un'intestazione personalizzata in tutte le risposte:
c.Set("X-Custom-Header", "Ciao, mondo")
// Procedi al middleware successivo:
return c.Next()
})
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Ciao, mondo!")
})
Il percorso per il metodo Use
può essere un percorso di mount o un percorso di prefisso, e limita il middleware da applicare solo alle richieste con percorsi che iniziano con quel percorso.
Aggiunta di Limitazioni dei Percorsi in Esecuzione
A causa di considerazioni di progettazione e prestazioni, non è supportato l'aggiunta dinamica di percorsi dopo l'avvio dell'applicazione. Assicurati che tutti i percorsi siano definiti prima dell'avvio dell'applicazione.
Raggruppamento
Se hai molti endpoint, puoi utilizzare Group
per organizzare i percorsi.
func main() {
app := fiber.New()
api := app.Group("/api", middleware) // /api
v1 := api.Group("/v1", middleware) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
v2 := api.Group("/v2", middleware) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
log.Fatal(app.Listen(":3000"))
}