gofiber / contrib

🧬 Repository for third party middlewares with dependencies
https://docs.gofiber.io/contrib/
MIT License
218 stars 115 forks source link

🚀 [Feature]: i18n refactoring from middleware to global container #1142

Open ReneWerner87 opened 3 months ago

ReneWerner87 commented 3 months ago

Feature Description

The i18n functionality is currently not perfect and prone to errors because the stats can change in between

The recommendation is to initialize a global container before the routes this container receives the supported languages as input and is initially initialized

TODO: provide example and more info

Additional Context (optional)

No response

Code Snippet (optional)

package main

import "github.com/gofiber/contrib/%package%"

func main() {
  // Steps to reproduce
}

Checklist:

ReneWerner87 commented 3 months ago

@coderabbitai please fill in the description of the proposal and add several examples of use with the new concept

coderabbitai[bot] commented 3 months ago

[!TIP] For best results, initiate chat on the files or code changes.

@ReneWerner87

Proposal Description

Currently, the i18n functionality is implemented as middleware, where the i18n bundle and localizer map are initialized for each request. This approach can lead to inconsistencies and errors, especially when the i18n state changes between requests.

To improve the robustness and performance of the i18n functionality, we propose refactoring it from middleware to a global container. This global container will be initialized once before the routes are set up and will manage the i18n bundle and localizer map. The global container will receive the supported languages and other configuration settings as input during initialization.

Key Changes:

  1. Global Initialization: Initialize the i18n bundle and localizer map globally before setting up routes.
  2. Configuration Management: Manage i18n configuration settings in a global container accessible throughout the application.
  3. Improved Performance: Reduce the overhead of initializing i18n components for each request.

Examples of Use

Example 1: Initializing the Global i18n Container

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/contrib/fiberi18n"
    "golang.org/x/text/language"
)

func main() {
    // Initialize global i18n container
    i18nConfig := &fiberi18n.Config{
        RootPath:         "./locales",
        DefaultLanguage:  language.English,
        AcceptLanguages:  []language.Tag{language.English, language.Chinese},
        FormatBundleFile: "json",
        UnmarshalFunc:    json.Unmarshal,
    }
    fiberi18n.Initialize(i18nConfig)

    // Create a new Fiber app
    app := fiber.New()

    // Set up routes
    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString(fiberi18n.MustLocalize(c, "welcome"))
    })

    app.Get("/:name", func(c *fiber.Ctx) error {
        return c.SendString(fiberi18n.MustLocalize(c, &i18n.LocalizeConfig{
            MessageID: "welcomeWithName",
            TemplateData: map[string]string{
                "name": c.Params("name"),
            },
        }))
    })

    // Start the server
    app.Listen(":3000")
}

Example 2: Accessing Localized Messages in Handlers

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/contrib/fiberi18n"
    "golang.org/x/text/language"
)

func main() {
    // Initialize global i18n container
    i18nConfig := &fiberi18n.Config{
        RootPath:         "./locales",
        DefaultLanguage:  language.English,
        AcceptLanguages:  []language.Tag{language.English, language.Chinese},
        FormatBundleFile: "json",
        UnmarshalFunc:    json.Unmarshal,
    }
    fiberi18n.Initialize(i18nConfig)

    // Create a new Fiber app
    app := fiber.New()

    // Set up routes
    app.Get("/", func(c *fiber.Ctx) error {
        message, err := fiberi18n.Localize(c, "welcome")
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
        }
        return c.SendString(message)
    })

    app.Get("/:name", func(c *fiber.Ctx) error {
        message, err := fiberi18n.Localize(c, &i18n.LocalizeConfig{
            MessageID: "welcomeWithName",
            TemplateData: map[string]string{
                "name": c.Params("name"),
            },
        })
        if err != nil {
            return c.Status(fiber.StatusInternalServerError).SendString(err.Error())
        }
        return c.SendString(message)
    })

    // Start the server
    app.Listen(":3000")
}

These examples demonstrate how to initialize the global i18n container and use it to access localized messages in route handlers. This approach ensures that the i18n configuration and state are managed globally, improving consistency and performance.

Analysis chain ---
Scripts executed The following scripts were executed for the analysis: --- Script: ```shell #!/bin/bash # Locate the i18n middleware implementation in the codebase. fd -e go -e md -e txt i18n ``` Length of output: 69 --- --- Script: ```shell #!/bin/bash # Display the contents of the i18n middleware implementation and test files. cat fiberi18n/i18n.go cat fiberi18n/i18n_test.go ``` Length of output: 8979

Learnings added ``` Learnt from: ReneWerner87 URL: https://github.com/gofiber/contrib/issues/1142 Timestamp: 2024-07-03T11:59:00.136Z Learning: The i18n functionality in the gofiber/contrib repository is being refactored from middleware to a global container to improve robustness and performance. The global container will be initialized once before setting up routes and will manage the i18n bundle and localizer map. ``` > Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).