Routen

Die Funktion von Routen im Go Fiber-Framework besteht darin, verschiedene URLs mit Verarbeitungsfunktionen zu verbinden, um die HTTP-Anforderungsverarbeitung zu unterstützen. Sie dient als Einstiegspunkt für alle Anfragen im Web-Framework.

Routen-Handler (Funktionen)

Registrieren Sie Routen, die an bestimmte HTTP-Methoden gebunden sind.

Hinweis: In einigen Frameworks werden Routen-Handler als Controller bezeichnet, was im Allgemeinen die gleiche Bedeutung hat – Bestimmung der Funktion (Methode) zur Behandlung der eingehenden HTTP-Anforderung.

Funktions-Signatur:

// HTTP-Methoden
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

// Mit Add können Sie Methoden als Werte festlegen
func (app *App) Add(method, path string, handlers ...Handler) Router

// All registriert die Route für alle HTTP-Methoden
// Ähnlich wie app.Use, aber bindet kein Präfix
func (app *App) All(path string, handlers ...Handler) Router

Beispiel:

// Einfacher GET-Handler
app.Get("/api/list", func(c *fiber.Ctx) error {
  return c.SendString("Dies ist eine GET-Anfrage!")
})

// Einfacher POST-Handler
app.Post("/api/register", func(c *fiber.Ctx) error {
  return c.SendString("Dies ist eine POST-Anfrage!")
})

Use wird verwendet, um Middleware und Präfix-URL-Interzeptoren zu laden. Diese Routen stimmen nur mit dem Anfang jedes Pfads überein, z.B. /john stimmt mit /john/doe, /johnnnnn usw. überein.

Funktions-Signatur für benutzerdefinierte Middleware:

func (app *App) Use(args ...interface{}) Router

Beispiel:

// Jede Anfrage abgleichen
app.Use(func(c *fiber.Ctx) error {
    return c.Next()
})

// Anfragen abgleichen, die mit /api beginnen
app.Use("/api", func(c *fiber.Ctx) error {
    return c.Next()
})

// Anfragen abgleichen, die mit /api oder /home beginnen (unterstützt mehrere Präfixe)
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
    return c.Next()
})

// Mehrere Handler hinzufügen
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()
})

Pfad

Der Routenpfad definiert zusammen mit der Anfrage-Methode die Endpunkte, auf die zugegriffen werden kann. Der Routenpfad kann ein String oder String-Muster sein.

Beispiele für routenpfadbasierte Zeichenketten:

// Dieser Routenpfad stimmt mit Anfragen an den Stamm-Pfad, "/," überein:
app.Get("/", func(c *fiber.Ctx) error {
  return c.SendString("Stamm-Pfad")
})

// Dieser Routenpfad stimmt mit Anfragen an "/about" überein:
app.Get("/about", func(c *fiber.Ctx) error {
  return c.SendString("Über uns")
})

// Dieser Routenpfad stimmt mit Anfragen an "/random.txt" überein:
app.Get("/random.txt", func(c *fiber.Ctx) error {
  return c.SendString("Zufällige.txt")

Ähnlich wie im ExpressJs-Framework ist die Reihenfolge, in der Routen deklariert werden, wichtig. Wenn eine Anfrage eingeht, werden die Routen in der Reihenfolge überprüft, in der sie deklariert wurden.

Bitte beachten Sie: Stellen Sie sicher, dass Routen mit variablen Parametern nach Routen mit festen Teilen geschrieben werden, um zu verhindern, dass diese variablen Teile fälschlicherweise übereinstimmen und zu unerwartetem Verhalten führen.

Routenparameter

Routenparameter sind dynamische Elemente in einer Route und können entweder benannte oder unbenannte Segmente sein. Diese Segmente werden verwendet, um Werte an bestimmten Positionen in der URL zu erfassen. Sie können die Params-Funktion verwenden, um diese Werte abzurufen, wobei der Funktionsparameter der Name des Routenparameters im Pfad ist, oder für unbenannte Parameter die Zeichen (*, +) und deren Anzahl.

Das Sternchen (*) oder Pluszeichen (+) repräsentiert gierige Parameter.

Routen bieten auch die Möglichkeit, optionale Parameter zu verwenden. Bei benannten Parametern folgt auf diese Parameter ein Fragezeichen (?), während das Pluszeichen nicht optional ist, und Sie Platzhalterzeichen verwenden können, um einen optionalen und gierigen Parameterbereich darzustellen.

Beispiel für die Definition einer Route mit Routenparametern

// Parameter
app.Get("/user/:name/books/:title", func(c *fiber.Ctx) error {
    fmt.Fprintf(c, "%s\n", c.Params("name"))
    fmt.Fprintf(c, "%s\n", c.Params("title"))
    return nil
})
// Pluszeichen - gierig - nicht optional
app.Get("/user/+", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("+"))
})

// Optionaler Parameter
app.Get("/user/:name?", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("name"))
})

// Platzhalterzeichen - gierig - optional
app.Get("/user/*", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("*"))
})

// Dieser Routenpfad passt zu der Anfrage "/v1/some/resource/name:customVerb", da die Parameterzeichen maskiert wurden
app.Get(`/v1/some/resource/name\:customVerb`, func(c *fiber.Ctx) error {
    return c.SendString("Hallo, Community")
})

Da Bindestriche (-) und Punkte (.) wörtlich interpretiert werden, können sie zusammen mit Routenparametern verwendet werden, um nützliche Zwecke zu erfüllen.

Alle speziellen Parameterzeichen können auch mithilfe von \ maskiert werden, und ihre Werte werden ignoriert. Wenn Sie sie in der Route verwenden möchten, wird empfohlen, Backticks `` zu verwenden. In der Go-Regular-Expression-Dokumentation werden sie immer verwendet, um sicherzustellen, dass keine Missverständnisse auftreten und die Maskierungszeichen das reguläre Ausdrucksmuster nicht unbeabsichtigt beeinflussen.

// http://localhost:3000/plantae/prunus.persica
app.Get("/plantae/:genus.:species", func(c *fiber.Ctx) error {
    fmt.Fprintf(c, "%s.%s\n", c.Params("genus"), c.Params("species"))
    return nil // prunus.persica
})
// http://localhost:3000/flights/LAX-SFO
app.Get("/flights/:from-:to", func(c *fiber.Ctx) error {
    fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to"))
    return nil // LAX-SFO
})

Unsere intelligente Routenführung erkennt, dass die eingeführten Parameterzeichen in diesem Fall Teil des Anforderungsrouten sind und entsprechend behandelt werden können.

// http://localhost:3000/shop/product/color:blue/size:xs
app.Get("/shop/product/color::color/size::size", func(c *fiber.Ctx) error {
    fmt.Fprintf(c, "%s:%s\n", c.Params("color"), c.Params("size"))
    return nil // blau:xs

Darüber hinaus können Routen mehrere Parameter und mehrere unbenannte Parameterzeichen hintereinander verwenden, wie Platzhalter- oder Pluszeichen, was die Möglichkeiten für Benutzer in den Routen erheblich erweitert.

// GET /@v1
// Params: "sign" -> "@", "param" -> "v1"
app.Get("/:sign:param", handler)

// GET /api-v1
// Params: "name" -> "v1" 
app.Get("/api-:name", handler)

// GET /customer/v1/cart/proxy
// Params: "*1" -> "customer/", "*2" -> "/cart"
app.Get("/*v1*/proxy", handler)

// GET /v1/brand/4/shop/blue/xs
// Params: "*1" -> "brand/4", "*2" -> "blue/xs"
app.Get("/v1/*/shop/*", handler)

Wir haben die Routenführung bereits an die Express-Routen angepasst, aber sie unterstützt noch keine regulären Ausdrücke, da diese relativ langsam sind.

Einschränkungen

Wenn die eingehende URL mit dem URL-Pfad übereinstimmt und der URL-Pfad über Parameter in Routenwerte unterteilt ist, werden die Einschränkungen ausgeführt. Diese Funktion wurde in v2.37.0 eingeführt und wurde von .NET Core inspiriert.

Einschränkungen dienen nicht der Parametervalidierung. Wenn die Einschränkung für den Parameterwert ungültig ist, gibt Fiber einen 404-Handler zurück.

Einschränkung Beispiel Beispieltreffer
int :id 123456789, -123456789
bool :active true, false
guid :id CD2C1638-1638-72D5-1638-DEADBEEF1638
float :weight 1,234, -1,001.01e8
minLen(value) :username<minLen(4)> test (mindestens 4 Zeichen)
maxLen(value) :filename<maxLen(8)> MyFile (bis zu 8 Zeichen)
len(length) :filename<len(12)> somefile.txt (12 Zeichen)
min(value) :age<min(18)> 19 (Ganzzahlwert muss mindestens 18 sein)
max(value) :age<max(120)> 91 (Ganzzahlwert darf 120 nicht überschreiten)
range(min,max) :age<range(18,120)> 91 (Ganzzahlwert muss mindestens 18 betragen, darf aber 120 nicht überschreiten)
alpha :name Rick (Zeichenfolge muss aus einem oder mehr alphanumerischen Zeichen bestehen, Groß- und Kleinschreibung wird nicht beachtet, a-z)
datetime :dob<datetime(2006\\-01\\-02)> 2005-11-01
regex(expression) :date<regex(\d{4}-\d{2}-\d{2})> 2022-08-27 (muss mit dem regulären Ausdruck übereinstimmen)

Beispiele

  • Einzelne Einschränkung
  • Mehrfache Einschränkungen
  • Reguläre Ausdruckseinschränkung
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 // GET /1 nicht gefunden

Sie können `;` verwenden, um mehrere Einschränkungen hinzuzufügen.

app.Get("/:test", func(c *fiber.Ctx) error { return c.SendString(c.Params("test")) })

// curl -X GET http://localhost:3000/120000 // GET /120000 nicht gefunden

// curl -X GET http://localhost:3000/1 // GET /1 nicht gefunden

// curl -X GET http://localhost:3000/250 // 250

Fiber kompiliert reguläre Ausdrucksabfragen im Voraus bei der Registrierung von Routen, daher entsteht kein Leistungsverlust für reguläre Ausdruckseinschränkungen.

```go
app.Get(`/:date`, func(c *fiber.Ctx) error {
  return c.SendString(c.Params("date"))
})

// curl -X GET http://localhost:3000/125 // GET /125 nicht gefunden

// curl -X GET http://localhost:3000/test // GET /test nicht gefunden

// curl -X GET http://localhost:3000/2022-08-27 // 2022-08-27

> Bei der Verwendung von Datum-Zeit-Einschränkungen (`*`,`+`,`?`,`:`,`/`,``,``,`>`,';`,`(`,`)`) verwenden Sie `\\` vor der Verwendung von Sonderzeichen in der Route, um Missverständnisse zu vermeiden.

**Beispiel für optionale Parameter**

Sie können auch Einschränkungen für optionale Parameter hinzufügen.
```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
// GET /7.0 nicht gefunden

Middleware

Funktionen, die entworfen sind, um Anfragen oder Antworten zu manipulieren, werden als Middleware-Funktionen bezeichnet. Next ist eine Fiber-Routing-Funktion, die beim Aufruf die next Funktion ausführt, die der aktuellen Route entspricht.

Beispiel für Middleware-Funktionen

app.Use(func(c *fiber.Ctx) error {
  // Setzen eines benutzerdefinierten Headers in allen Antworten:
  c.Set("X-Custom-Header", "Hallo, Welt")

  // Fortfahren zur nächsten Middleware:
  return c.Next()
})

app.Get("/", func(c *fiber.Ctx) error {
  return c.SendString("Hallo, Welt!")
})

Der Pfad für die Use-Methode kann ein Mount-Pfad oder ein Präfix-Pfad sein und beschränkt die Middleware darauf, nur auf Anfragen angewendet zu werden, deren Pfade mit diesem Pfad beginnen.

Hinzufügen von Routenbeschränkungen zur Laufzeit

Aufgrund von Design- und Leistungsüberlegungen wird das dynamische Hinzufügen von Routen nach dem Start der Anwendung nicht unterstützt. Stellen Sie bitte sicher, dass alle Routen vor dem Start der Anwendung definiert sind.

Gruppierung

Wenn Sie viele Endpunkte haben, können Sie Group verwenden, um Routen zu organisieren.

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