Roteamento

O papel da rota no framework Go Fiber é vincular diferentes URLs a funções de tratamento, a fim de oferecer suporte ao processamento de solicitações HTTP. Ele serve como ponto de entrada para todas as solicitações do framework da web.

Manipuladores de Rota (Funções)

Registre rotas vinculadas a métodos HTTP específicos.

Nota: Em alguns frameworks, os manipuladores de rota são chamados de controladores, que geralmente têm o mesmo significado – determinar qual função (método) lidará com a solicitação HTTP recebida.

Assinatura da Função:

// Métodos 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 permite que você especifique métodos como valores
func (app *App) Add(method, path string, handlers ...Handler) Router

// All registra a rota em todos os métodos HTTP
// Similar a app.Use, mas não vincula um prefixo
func (app *App) All(path string, handlers ...Handler) Router

Exemplo:

// Manipulador GET simples
app.Get("/api/list", func(c *fiber.Ctx) error {
	return c.SendString("Esta é uma solicitação GET!")
})

// Manipulador POST simples
app.Post("/api/register", func(c *fiber.Ctx) error {
	return c.SendString("Esta é uma solicitação POST!")
})

Use é usado para carregar middleware e interceptadores de URL de prefixo. Essas rotas só correspondem ao início de cada caminho, por exemplo, /john corresponderá a /john/doe, /johnnnnn, e assim por diante.

Assinatura personalizada da função de middleware:

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

Exemplo:

// Corresponder a qualquer solicitação
app.Use(func(c *fiber.Ctx) error {
	return c.Next()
})

// Corresponder a solicitações começando com /api
app.Use("/api", func(c *fiber.Ctx) error {
	return c.Next()
})

// Corresponder a solicitações começando com /api ou /home (suporta vários prefixos)
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
	return c.Next()
})

// Adicionar vários manipuladores
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()
})

Caminho

O caminho da rota, juntamente com o método de solicitação, define os pontos de extremidade que podem ser acessados. O caminho da rota pode ser uma string ou um padrão de string.

Exemplos de caminhos de rota baseados em string

// Este caminho de rota corresponderá a solicitações para o caminho raiz, "/":
app.Get("/", func(c *fiber.Ctx) error {
	return c.SendString("Caminho raiz")
})

// Este caminho de rota corresponderá a solicitações para "/about":
app.Get("/about", func(c *fiber.Ctx) error {
	return c.SendString("Sobre")
})

// Este caminho de rota corresponderá a solicitações para "/random.txt":
app.Get("/random.txt", func(c *fiber.Ctx) error {
	return c.SendString("Random.txt")

Assim como no framework ExpressJs, a ordem em que as rotas são declaradas é importante. Quando uma solicitação é recebida, as rotas são verificadas na ordem em que são declaradas.

Por favor, note: Garanta que as rotas com parâmetros variáveis sejam escritas após as rotas que contêm partes fixas para evitar que essas partes variáveis sejam correspondidas inadvertidamente, o que poderia levar a um comportamento inesperado.

Parâmetros de Rota

Os parâmetros de rota são elementos dinâmicos em uma rota e podem ser segmentos nomeados ou sem nome. Esses segmentos são usados para capturar valores em posições específicas na URL. Você pode usar a função Params para recuperar esses valores, onde o parâmetro da função é o nome do parâmetro de rota no caminho, ou para parâmetros sem nome, são os caracteres (*, +) e sua contagem.

O curinga (*) ou sinal de adição (+) representa parâmetros gananciosos.

As rotas também oferecem a possibilidade de usar parâmetros opcionais. Para parâmetros nomeados, esses parâmetros são seguidos por um ponto de interrogação (?), enquanto o sinal de adição não é opcional, e você pode usar caracteres curinga para representar um intervalo de parâmetros opcional e ganancioso.

Exemplo de definição de uma rota com parâmetros de rota

// Parâmetros
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
})
// Mais - ganancioso - não opcional
app.Get("/user/+", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("+"))
})

// Parâmetro opcional
app.Get("/user/:name?", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("name"))
})

// Curinga - ganancioso - opcional
app.Get("/user/*", func(c *fiber.Ctx) error {
    return c.SendString(c.Params("*"))
})

// Esta rota corresponderá à solicitação "/v1/some/resource/name:customVerb" porque os caracteres do parâmetro foram escapados
app.Get(`/v1/some/resource/name\:customVerb`, func(c *fiber.Ctx) error {
    return c.SendString("Olá, Comunidade")
})

Como os hífens (-) e os pontos (.) são interpretados literalmente, eles podem ser usados juntamente com parâmetros de rota para alcançar propósitos úteis.

Todos os caracteres especiais de parâmetro também podem ser escapados usando \ e seus valores serão ignorados, então se você deseja usá-los na rota. É recomendado usar a crase ``, como na documentação de expressão regular do Go, onde sempre são usados para garantir que não haja ambiguidade e os caracteres de escape não afetem inadvertidamente o padrão da expressão regular.

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

Nossa roteirização inteligente reconhece que os caracteres de parâmetro introduzidos neste caso devem fazer parte da rota de solicitação e pode lidar com isso como tal.

// 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 // blue:xs

Além disso, as rotas podem usar vários parâmetros e caracteres de parâmetro sem nome consecutivos, como caracteres curinga ou de adição, expandindo muito as possibilidades para os usuários nas rotas.

// 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)

Já adaptamos a roteirização para a roteirização do Express, mas ainda não oferece suporte a expressões regulares porque elas são relativamente lentas.

Restrições

Quando houver uma correspondência com a URL de entrada e o caminho da URL for dividido em valores de rota por meio de parâmetros, as restrições serão executadas. Este recurso foi introduzido na v2.37.0 e foi inspirado no .NET Core.

As restrições não são para validação de parâmetros. Se a restrição for inválida para o valor do parâmetro, o Fiber retornará um manipulador 404.

Restrição Exemplo Corresponde a exemplos
int :id 123456789, -123456789
bool :active true, false
guid :id CD2C1638-1638-72D5-1638-DEADBEEF1638
float :weight 1.234, -1,001.01e8
minLen(valor) :username<minLen(4)> teste (pelo menos 4 caracteres)
maxLen(valor) :filename<maxLen(8)> MeuArquivo (até 8 caracteres)
len(comprimento) :filename<len(12)> algumarquivo.txt (12 caracteres)
min(valor) :age<min(18)> 19 (valor inteiro deve ter no mínimo 18)
max(valor) :age<max(120)> 91 (valor inteiro não pode exceder 120)
range(min,max) :age<range(18,120)> 91 (valor inteiro deve ter no mínimo 18 e não pode exceder 120)
alpha :name Rick (cadeia de caracteres deve consistir em uma ou mais letras do alfabeto, sem diferenciação de maiúsculas e minúsculas, a-z)
datetime :dob<datetime(2006\\-01\\-02)> 2005-11-01
regex(expressão) :date<regex(\d{4}-\d{2}-\d{2})> 2022-08-27 (deve corresponder à expressão regular)

Exemplos

  • Restrição Única
  • Múltiplas Restrições
  • Restrição de Expressão Regular
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 // Não é possível encontrar GET /1


Você pode usar `;` para adicionar múltiplas restrições.

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

// curl -X GET http://localhost:3000/120000 // Não é possível encontrar GET /120000

// curl -X GET http://localhost:3000/1 // Não é possível encontrar GET /1

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


O Fiber pré-compila consultas de expressões regulares ao registrar rotas, portanto, não há sobrecarga de desempenho para as restrições de expressão regular.

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

// curl -X GET http://localhost:3000/125 // Não é possível encontrar GET /125

// curl -X GET http://localhost:3000/test // Não é possível encontrar GET /test

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


> Ao usar restrições de data e hora (`*`,`+`,`?`,`:`,`/`,``,``,`>`,';`,`(`,`)`), use `\\` antes de usar caracteres especiais na rota para evitar má interpretação.

**Exemplo de Parâmetro Opcional**

Também é possível adicionar restrições a parâmetros opcionais.
```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
// Não é possível encontrar GET /7.0

Middleware

Funções projetadas para manipular solicitações ou respostas são chamadas de funções de middleware. Next é uma função de roteamento do Fiber que, quando chamada, executa a função next que corresponde à rota atual.

Exemplo de Função de Middleware

app.Use(func(c *fiber.Ctx) error {
  // Definir um cabeçalho personalizado em todas as respostas:
  c.Set("X-Custom-Header", "Olá, mundo")

  // Prossiga para o próximo middleware:
  return c.Next()
})

app.Get("/", func(c *fiber.Ctx) error {
  return c.SendString("Olá, mundo!")
})

O caminho para o método Use pode ser um caminho de montagem ou prefixo, e ele restringe o middleware a ser aplicado apenas a solicitações com caminhos que começam com esse caminho.

Adicionando Limitações de Rota em Tempo de Execução

Devido a considerações de design e desempenho, a adição dinâmica de rotas após a inicialização da aplicação não é suportada. Por favor, certifique-se de que todas as rotas estejam definidas antes que a aplicação seja iniciada.

Agrupamento

Se você tiver muitos endpoints, você pode usar Group para organizar rotas.

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