Description
Feature Proposal Description
This proposal aims to introduce Application State Management feature in Fiber to enable the sharing of stateful data across middleware and request handlers efficiently. This is a feature supported in other language frameworks for example: Starlette and FastAPI.
- Introduce App State Management: Implement a state management system that allows storing and accessing application-wide state.
- Middleware and Handler Integration: Ensure seamless integration with existing middleware and request handlers.
- Ease of Use: Provide a simple and intuitive API for developers to interact with the application state.
- Performance: Ensure that the state management system does not compromise the performance of Fiber.
Sources:
- https://www.starlette.io/applications/#storing-state-on-the-app-instance
- https://fastapi.tiangolo.com/reference/fastapi/#fastapi.FastAPI.state
Alignment with Express API
In fiber these proposal is similar to ctx.Locals
but applies to the whole application. Resources stored in the state
can be accessed by multiple handlers, middlewares, etc.
In Express.js it's similar to app.locals
, but in express the values can only be used when rendering templates.
HTTP RFC Standards Compliance
N/a
API Stability
API Methods
- Set: Set a key-value pair in the application state.
- What do we do if the Key already exists?
- Do we add
MustSet
, to panic if key already exists?
- Get: Retrieve a value by key from the application state.
- MustGet: Retrieve a value by key from the application state, panic if not found.
- Delete: Remove a key-value pair from the application state.
- This probably requires a mutex.
- Exists: Check if a key exists in the application state.
We could also add specific Get
functions for specific common types: int, string, float, etc. For example, for getting a string from the app.State:
func (s *State) GetString(key string) (string, bool) {
value, exists := s.state[key]
if !exists {
return "", false
}
str, ok := value.(string)
return str, ok
}
It would be the responsibility of the developer to call to appropriate function.
Feature Examples
func main() {
app := fiber.New()
// Create and set the database client
connString := "postgres://username:password@localhost:5432/database_name"
conn, _ := pgx.Connect(context.Background(), connString)
defer conn.Close(context.Background())
// Store DB client in App State
app.State.Set("db", conn)
app.Get("/", func(c *fiber.Ctx) error {
// Access the database connection from the AppState
db, exists := app.State.Get("db")
if !exists {
return c.Status(fiber.StatusInternalServerError).SendString("Database connection not found")
}
// Use the database connection
pgxConn := db.(*pgx.Conn)
var greeting string
err := pgxConn.QueryRow(context.Background(), "SELECT 'Hello, world!'").Scan(&greeting)
if err != nil {
return c.Status(fiber.StatusInternalServerError).SendString("Failed to execute query")
}
return c.SendString(greeting)
})
app.Listen(":3000")
}
Checklist:
- I agree to follow Fiber's Code of Conduct.
- I have searched for existing issues that describe my proposal before opening this one.
- I understand that a proposal that does not meet these guidelines may be closed without explanation.
Metadata
Metadata
Assignees
Type
Projects
Status
Todo