Skip to content

📝 [Proposal]: Standardization of Middleware Context Key Prevent Collisions (Breaking Change) #2684

@sixcolors

Description

@sixcolors

Issue Description

The middleware in GoFiber sets string values to ctx.Locals using non-standardized default context keys, and since these defaults are non-zero values this forces their existence. This behavior can lead to conflicts and confusion for users. Furthermore, the specificity of these context keys, i.e., their purpose and potential conflicts, should be addressed.

Additionally, the presence of dots or dashes in context keys can cause issues when using PassLocalsToViews, which injects key-value pairs into various template engines. Even template engines that correctly handle dots and dashes may cause fiber to feel hacked together and not polished.

Below are some examples of middleware and their non-standardized default context keys:

  • BasicAuth:

    • ContextUsername: "username"
    • ContextPassword: "password"
  • CSRF:

    • SessionKey: "fiber.csrf.token"
    • HandlerContextKey: "fiber.csrf.handler"
  • Keyauth:

    • ContextKey: "token"
  • RequestID:

    • ContextKey: "requestid"
  • Paseto:

    • ContextKey: "auth-token"
  • JWT:

    • ContextKey: "user"

Key Specificity and Conflicts

The default context keys provided by the middleware lack specificity, making it unclear what each key is for. This lack of clarity can lead to conflicts when multiple middleware components use similar or identical context keys for different purposes. Additionally, these keys are used to set string values to ctx.Locals, which can lead to unintended side effects if conflicts occur.

Key Specificity Example

For instance, it's not immediately clear what "ContextUsername" and "ContextPassword" refer to in the BasicAuth middleware, and what kind of string values they set in ctx.Locals. Providing more specific key names can enhance user understanding.

Potential Conflicts

Additionally, the non-standardized default context keys across middleware components can result in unintended conflicts when setting values in ctx.Locals. If multiple middleware components use the same key name for different purposes, it can lead to unexpected behavior and errors in ctx.Locals.

Dots and Dashes in Context Keys

The use of dots or dashes in context keys, while generally accepted in many scenarios, can pose challenges when using PassLocalsToViews. This middleware injects key-value pairs into various template engines, including HTML, Django, Pug, Mustache, etc. These template engines may not handle dots and dashes correctly or may make it cumbersome to access keys with such characters.

Proposed Solution

The proposed solution should aim to address both key specificity and potential conflicts when setting string values to ctx.Locals. You may consider one of the following approaches:

### Context Key Formatting
Consider adopting a standardized naming convention for context keys to enhance consistency and clarity. Here are some suggestions:

  • Choose a default camelCase, PascalCase or snake_case for all middlware context keys.
  • Prefix context keys with "fiber" and middleware name (e.g., fiberCsrfToken or fiberBasicAuthUsername) or just the middleware name (e.g., csrfToken or basicAuthUsername).

Follow convention from context by using unexported key type to avoid collisions. See also Go Concurrency Patterns: Context.

Breaking Change

The proposed solution represents a breaking change. This means that implementing these changes in GoFiber would require adjustments by users. Here's the context and reasons behind this breaking change:

Context

The current non-standardized context key names, such as "user" or "token," can lead to confusion and conflicts, making it challenging for users to understand their purpose and behaviour. By using functions following the naming convention pkg.*FromContext(ctx) (eg basicauth.UsernameFromContext(ctx), basicauth.PasswordFromContext(ctx)) we can improve clarity and consistency. In the case where the package will return only one value use pkg.FromContext(ctx) (eg jwt.FromContext(ctx)).

Rationale

  1. Enhanced User Experience: Standardized ways to access values from middleware. This leads to an improved overall user experience when working with GoFiber middleware.

  2. Reduced Conflicts: Using unexported types for key values in packages eliminates the potential for collisions.

  3. Consistency: A consistent approach to accessing values simplifies the customization process for users.

  4. Clarity in Documentation: Standardized functions also enhance the clarity of documentation. Documentation can provide clear examples and guidance using standardized naming conventions, making it more accessible to users.

Impact on Users

This is a breaking change for users that access values stored in the context.

Migration Plan

Documentation requires an update and the change should be mentioned in the release notes for v3.

By implementing this breaking change, GoFiber would provide a more polished and user-friendly experience and offer better consistency throughout the middleware ecosystem.

Additional Context (optional)

#2682

gofiber/template#307

Checklist:

  • I agree to follow Fiber's Code of Conduct.
  • I have checked for existing issues that describe my suggestion prior to opening this one.
  • I understand that improperly formatted feature requests may be closed without explanation.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions