ACHMAD IRIANTO EKA PUTRA 9a56a1bf6d
v3: Add QueryParser for get query using generic (#2776)
* Add QueryParser method and tests

Introduced a new method, QueryParser, to parse query parameters from a given context into specified types: integer, boolean, float, and string. The method provides default values for empty or invalid keys. Corresponding tests for each type have also been added to validate the functionality.

* Refactor QueryParser and add string support

Refactored the existing QueryParser method in the code to simplify its structure. Instead of reflecting on types, it now uses explicit type checking. In addition to the existing support for integers, booleans, and floats, the QueryParser method now also supports string parsing. Corresponding tests for the updated method and new feature were added as well.

* Update example call in method comment

Updated the method call example in the comment for the Query function in the ctx.go file. Previously, it was incorrectly demonstrating a call to "QueryParser("wanna_cake", 1)", but this has been updated to correctly represent the method it is commenting, resulting in "Query("wanna_cake", 1)".

* Refactor Query function in ctx.go

The update introduces better type assertion handling in the Query function. A switch statement is now employed to determine the type of the value as opposed to the previous if clauses. In addition, a validation step has been added to ensure the context passed into the function is of the correct type.

* Refactor type handling in Query function

The Query function in ctx.go has been refactored for better and clearer type handling. The code now uses a 'QueryType' interface, replacing explicit string, bool, float, and int declarations. This change also improves the error message when a type assertion fails, making it more descriptive about the specific failure.

* Add type assertion check in ctx.go

Updated the code in ctx.go to add a type assertion check for all case statements. The function now checks if the returned value is of the expected type, and if not, it throws a panic with a description of the failed type assertion.

* Refactor Query function to support more data types

The Query function has been expanded to support a broader range of data types. This includes support for extracting query parameters as different types of integers (both signed and unsigned), strings, floats, and booleans from the request's URI. The function now includes comprehensive parsing capabilities that allow for improved handling of different data types.

* Refactor Query function documentation

The documentation for the Query function has been updated to emphasize its versatility in handling various data types. The changes also clarify how the function operates and demonstrates the usage and benefits of providing a defaultValue. The different variations of QueryBool, QueryFloat, and QueryInt were removed, as they are now encompassed by the enhanced Query function.

* Add benchmark tests for Query function

Benchmark tests have been added to evaluate the performance of the Query function for different data types. These tests will help in assessing the efficiency of the function when processing various queries. The addition of these benchmarks will aid in future optimizations and enhancements of the function.

* Update generic Query function signature

The signature of the generic Query function has been updated to accept different types of data as arguments. The change improves flexibility of the function by allowing it to handle different data types, effectively making it a versatile tool in processing various queries.

* Modify `ctx.Query()` calls in documentation

`ctx.Query()` calls in the ctx.md documentation file were updated to remove the `ctx.` prefix. This is consistent with the typical use cases and makes the code examples more clear and easy to understand.

* Refactored assertValueType function and improved query parameter documentation

Updated the assertValueType function to utilize the utils.UnsafeBytes method for byte conversion. Enhanced the documentation for query parameter types to offer clearer, more comprehensive explanations and examples, including QueryTypeInteger, QueryTypeFloat, and subcategories.

* Update Query method calls to use new fiber.Query syntax

In this commit, the conventional `c.Query()` calls across multiple middleware and document files are updated to use the new `fiber.Query` syntax. The changes align with the updated function signatures in Fiber library that provides type-specific querying. These enhancements contribute to the project's overall robustness and consistency.

* Add Query method to get query string parameters

* Replace 'utils.UnsafeBytes' with 'ctx.app.getBytes'

In the query method, the utils.UnsafeBytes function was replaced with the ctx.app.getBytes method. This change enhances the extraction of query string parameters by making it safer and more context-specific.

* Refactor parsing functions in query handlers

The parsing functions in query handlers have been refactored to simplify the process. Parsing code has been extracted into dedicated functions like 'parseIntWithDefault' and 'parseFloatWithDefault', and they now reside in a new utils file. This modularization improves readability and maintainability of the code. Additionally, documentation is updated to reflect the changes.

* Refactor parsing functions in ctx.go

The parsing functions have been restructured to enhance readability and reduce repetition in the ctx.go file. This was achieved by creating generalised parsing functions that handle defaults and ensure the correct value type is returned. As a result, various single-use parsing functions in the utils.go file have been removed.

* Refactor code to centralize parsing functions
2024-01-19 14:43:44 +01:00
2023-03-06 17:35:39 +03:00
v2
2020-09-13 11:20:11 +02:00
2023-11-07 20:22:31 +03:00
2023-11-14 08:18:46 +01:00
2023-02-09 22:33:45 +03:00
2023-11-07 20:22:31 +03:00
2023-11-07 20:22:31 +03:00
2021-06-23 06:28:46 +02:00
2023-10-05 13:14:30 +02:00
2023-10-05 13:14:30 +02:00
2023-11-07 20:22:31 +03:00
2023-08-05 22:25:21 +03:00
2023-08-05 22:25:21 +03:00
2023-11-07 20:22:31 +03:00

Fiber

Fiber is an Express inspired web framework built on top of Fasthttp, the fastest HTTP engine for Go. Designed to ease things up for fast development with zero memory allocation and performance in mind.

Quickstart

package main

import "github.com/gofiber/fiber/v3"

func main() {
    app := fiber.New()

    app.Get("/", func(c fiber.Ctx) error {
        return c.SendString("Hello, World 👋!")
    })

    app.Listen(":3000")
}

🤖 Benchmarks

These tests are performed by TechEmpower and Go Web. If you want to see all the results, please visit our Wiki.

⚙️ Installation

Make sure you have Go installed (download). Version 1.17 or higher is required.

Initialize your project by creating a folder and then running go mod init github.com/your/repo (learn more) inside the folder. Then install Fiber with the go get command:

go get -u github.com/gofiber/fiber/v3

🎯 Features

💡 Philosophy

New gophers that make the switch from Node.js to Go are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a web framework, was created with the idea of minimalism and follows the UNIX way, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.

Fiber is inspired by Express, the most popular web framework on the Internet. We combined the ease of Express and raw performance of Go. If you have ever implemented a web application in Node.js (using Express or similar), then many methods and principles will seem very common to you.

We listen to our users in issues, Discord channel and all over the Internet to create a fast, flexible and friendly Go web framework for any task, deadline and developer skill! Just like Express does in the JavaScript world.

⚠️ Limitations

  • Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber 2.40.0 has been tested with Go versions 1.17 to 1.21.
  • Fiber is not compatible with net/http interfaces. This means you will not be able to use projects like gqlgen, go-swagger, or any others which are part of the net/http ecosystem.

👀 Examples

Listed below are some of the common examples. If you want to see more code examples, please visit our Recipes repository or visit our hosted API documentation.

📖 Basic Routing

func main() {
    app := fiber.New()

    // GET /api/register
    app.Get("/api/*", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("✋ %s", c.Params("*"))
        return c.SendString(msg) // => ✋ register
    })

    // GET /flights/LAX-SFO
    app.Get("/flights/:from-:to", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
        return c.SendString(msg) // => 💸 From: LAX, To: SFO
    })

    // GET /dictionary.txt
    app.Get("/:file.:ext", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
        return c.SendString(msg) // => 📃 dictionary.txt
    })

    // GET /john/75
    app.Get("/:name/:age/:gender?", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
        return c.SendString(msg) // => 👴 john is 75 years old
    })

    // GET /john
    app.Get("/:name", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
        return c.SendString(msg) // => Hello john 👋!
    })

    log.Fatal(app.Listen(":3000"))
}

📖 Route Naming

func main() {
    app := fiber.New()

    // GET /api/register
    app.Get("/api/*", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("✋ %s", c.Params("*"))
        return c.SendString(msg) // => ✋ register
    }).Name("api")

    data, _ := json.MarshalIndent(app.GetRoute("api"), "", "  ")
    fmt.Print(string(data))
    // Prints:
    // {
    //    "method": "GET",
    //    "name": "api",
    //    "path": "/api/*",
    //    "params": [
    //      "*1"
    //    ]
    // }


    log.Fatal(app.Listen(":3000"))
}

📖 Serving Static Files

func main() {
    app := fiber.New()

    app.Static("/", "./public")
    // => http://localhost:3000/js/script.js
    // => http://localhost:3000/css/style.css

    app.Static("/prefix", "./public")
    // => http://localhost:3000/prefix/js/script.js
    // => http://localhost:3000/prefix/css/style.css

    app.Static("*", "./public/index.html")
    // => http://localhost:3000/any/path/shows/index/html

    log.Fatal(app.Listen(":3000"))
}

📖 Middleware & Next

func main() {
    app := fiber.New()

    // Match any route
    app.Use(func(c fiber.Ctx) error {
        fmt.Println("🥇 First handler")
        return c.Next()
    })

    // Match all routes starting with /api
    app.Use("/api", func(c fiber.Ctx) error {
        fmt.Println("🥈 Second handler")
        return c.Next()
    })

    // GET /api/list
    app.Get("/api/list", func(c fiber.Ctx) error {
        fmt.Println("🥉 Last handler")
        return c.SendString("Hello, World 👋!")
    })

    log.Fatal(app.Listen(":3000"))
}

📚 Show more code examples

Views engines

📖 Config 📖 Engines 📖 Render

Fiber defaults to the html/template when no view engine is set.

If you want to execute partials or use a different engine like amber, handlebars, mustache or pug etc..

Checkout our Template package that support multiple view engines.

package main

import (
    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/template/pug"
)

func main() {
    // You can setup Views engine before initiation app:
    app := fiber.New(fiber.Config{
        Views: pug.New("./views", ".pug"),
    })

    // And now, you can call template `./views/home.pug` like this:
    app.Get("/", func(c fiber.Ctx) error {
        return c.Render("home", fiber.Map{
            "title": "Homepage",
            "year":  1999,
        })
    })

    log.Fatal(app.Listen(":3000"))
}

Grouping routes into chains

📖 Group

func middleware(c fiber.Ctx) error {
    fmt.Println("Don't mind me!")
    return c.Next()
}

func handler(c fiber.Ctx) error {
    return c.SendString(c.Path())
}

func main() {
    app := fiber.New()

    // Root API route
    api := app.Group("/api", middleware) // /api

    // API v1 routes
    v1 := api.Group("/v1", middleware) // /api/v1
    v1.Get("/list", handler)           // /api/v1/list
    v1.Get("/user", handler)           // /api/v1/user

    // API v2 routes
    v2 := api.Group("/v2", middleware) // /api/v2
    v2.Get("/list", handler)           // /api/v2/list
    v2.Get("/user", handler)           // /api/v2/user

    // ...
}

Middleware logger

📖 Logger

package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/logger"
)

func main() {
    app := fiber.New()

    app.Use(logger.New())

    // ...

    log.Fatal(app.Listen(":3000"))
}

Cross-Origin Resource Sharing (CORS)

📖 CORS

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/cors"
)

func main() {
    app := fiber.New()

    app.Use(cors.New())

    // ...

    log.Fatal(app.Listen(":3000"))
}

Check CORS by passing any domain in Origin header:

curl -H "Origin: http://example.com" --verbose http://localhost:3000

Custom 404 response

📖 HTTP Methods

func main() {
    app := fiber.New()

    app.Static("/", "./public")

    app.Get("/demo", func(c fiber.Ctx) error {
        return c.SendString("This is a demo!")
    })

    app.Post("/register", func(c fiber.Ctx) error {
        return c.SendString("Welcome!")
    })

    // Last middleware to match anything
    app.Use(func(c fiber.Ctx) error {
        return c.SendStatus(404)
        // => 404 "Not Found"
    })

    log.Fatal(app.Listen(":3000"))
}

JSON Response

📖 JSON

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    app := fiber.New()

    app.Get("/user", func(c fiber.Ctx) error {
        return c.JSON(&User{"John", 20})
        // => {"name":"John", "age":20}
    })

    app.Get("/json", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "success": true,
            "message": "Hi John!",
        })
        // => {"success":true, "message":"Hi John!"}
    })

    log.Fatal(app.Listen(":3000"))
}

WebSocket Upgrade

📖 Websocket

import (
    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/websocket"
)

func main() {
  app := fiber.New()

  app.Get("/ws", websocket.New(func(c *websocket.Conn) {
    for {
      mt, msg, err := c.ReadMessage()
      if err != nil {
        log.Println("read:", err)
        break
      }
      log.Printf("recv: %s", msg)
      err = c.WriteMessage(mt, msg)
      if err != nil {
        log.Println("write:", err)
        break
      }
    }
  }))

  log.Fatal(app.Listen(":3000"))
  // ws://localhost:3000/ws
}

Server-Sent Events

📖 More Info

import (
    "github.com/gofiber/fiber/v3"
    "github.com/valyala/fasthttp"
)

func main() {
  app := fiber.New()

  app.Get("/sse", func(c fiber.Ctx) error {
    c.Set("Content-Type", "text/event-stream")
    c.Set("Cache-Control", "no-cache")
    c.Set("Connection", "keep-alive")
    c.Set("Transfer-Encoding", "chunked")

    c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
      fmt.Println("WRITER")
      var i int

      for {
        i++
        msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
        fmt.Fprintf(w, "data: Message: %s\n\n", msg)
        fmt.Println(msg)

        w.Flush()
        time.Sleep(5 * time.Second)
      }
    }))

    return nil
  })

  log.Fatal(app.Listen(":3000"))
}

Recover middleware

📖 Recover

import (
    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/recover"
)

func main() {
    app := fiber.New()

    app.Use(recover.New())

    app.Get("/", func(c fiber.Ctx) error {
        panic("normally this would crash your app")
    })

    log.Fatal(app.Listen(":3000"))
}

Using Trusted Proxy

📖 Config

import (
    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/recover"
)

func main() {
    app := fiber.New(fiber.Config{
        EnableTrustedProxyCheck: true,
        TrustedProxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
        ProxyHeader: fiber.HeaderXForwardedFor,
    })

    // ...

    log.Fatal(app.Listen(":3000"))
}

🧬 Internal Middleware

Here is a list of middleware that are included within the Fiber framework.

Middleware Description
basicauth Basic auth middleware provides an HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials.
cache Intercept and cache responses
compress Compression middleware for Fiber, it supports deflate, gzip and brotli by default.
cors Enable cross-origin resource sharing CORS with various options.
csrf Protect from CSRF exploits.
encryptcookie Encrypt middleware which encrypts cookie values.
envvar Expose environment variables with providing an optional config.
etag ETag middleware that lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed.
expvar Expvar middleware that serves via its HTTP server runtime exposed variants in the JSON format.
favicon Ignore favicon from logs or serve from memory if a file path is provided.
filesystem FileSystem middleware for Fiber, special thanks and credits to Alireza Salary
limiter Rate-limiting middleware for Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset.
logger HTTP request/response logger.
monitor Monitor middleware that reports server metrics, inspired by express-status-monitor
pprof Special thanks to Matthew Lee @mthli
proxy Allows you to proxy requests to a multiple servers
recover Recover middleware recovers from panics anywhere in the stack chain and handles the control to the centralized ErrorHandler.
requestid Adds a requestid to every request.
session Session middleware. NOTE: This middleware uses our Storage package.
skip Skip middleware that skips a wrapped handler if a predicate is true.
rewrite Rewrite middleware rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links.
timeout Adds a max time for a request and forwards to ErrorHandler if it is exceeded.
adaptor Converter for net/http handlers to/from Fiber request handlers, special thanks to @arsmn!
helmet Helps secure your apps by setting various HTTP headers.
redirect Redirect middleware
keyauth Key auth middleware provides a key based authentication.

🧬 External Middleware

List of externally hosted middleware modules and maintained by the Fiber team.

Middleware Description
jwt JWT returns a JSON Web Token JWT auth middleware.
storage Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares.
template This package contains 8 template engines that can be used with Fiber v1.10.x Go version 1.13 or higher is required.
websocket Based on Fasthttp WebSocket for Fiber with Locals support!

🕶️ Awesome List

For more articles, middlewares, examples or tools check our awesome list.

👍 Contribute

If you want to say thank you and/or support the active development of Fiber:

  1. Add a GitHub Star to the project.
  2. Tweet about the project on your 𝕏 (Twitter).
  3. Write a review or tutorial on Medium, Dev.to or personal blog.
  4. Support the project by donating a cup of coffee.

Supporters

Fiber is an open source project that runs on donations to pay the bills e.g. our domain name, gitbook, netlify and serverless hosting. If you want to support Fiber, you can buy a coffee here.

User Donation
@destari x 10
@dembygenesis x 5
@thomasvvugt x 5
@hendratommy x 5
@ekaputra07 x 5
@jorgefuertes x 5
@candidosales x 5
@l0nax x 3
@bihe x 3
@justdave x 3
@koddr x 1
@lapolinar x 1
@diegowifi x 1
@ssimk0 x 1
@raymayemir x 1
@melkorm x 1
@marvinjwendt x 1
@toishy x 1

💻 Code Contributors

Code Contributors

Stargazers

Stargazers over time

⚠️ License

Copyright (c) 2019-present Fenny and Contributors. Fiber is free and open-source software licensed under the MIT License. Official logo was created by Vic Shóstak and distributed under Creative Commons license (CC BY-SA 4.0 International).

Third-party library licenses

Languages
Go 100%