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