You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current API for Ctx.Format does not align with res.format from Express. While they both perform content negotiation, the usage is different (see below for a comparison). This may be confusing for Gophers coming from Express who expect to be able to add their own handlers.
I propose reworking Ctx.Format to take a mapping of accept types to handlers. We can move the existing Ctx.Format functionality to a separate method (e.g., Ctx.AutoFormat)
Alignment with Express API
In Express, res.format is used to perform content negotiation and call a different handler based on the result. The handlers are fully user-defined aside from the default handler which will send a 406 HTML response.
From https://expressjs.com/en/api.html#res.format
res.format({'text/plain': function(){res.send('hey')},'text/html': function(){res.send('<p>hey</p>')},'application/json': function(){res.send({message: 'hey'})},default: function(){// log the request and respond with 406res.status(406).send('Not Acceptable')}})
Fiber's Ctx.Format has automatic handlers for a fixed set of Accept headers. The usage is different; it hides details of the request's Accept header and the outgoing Content Type from the implementer.
RFC-9110 does not specify how servers should reply to requests with respect to content - it simply gives various suggestions and algorithms. res.format follows the proactive negotiation algorithm.
API Stability
The new Ctx.Format should be in line with res.format, meaning it should have a stable API. The main risk for API stability is the data structure in which the handlers are passed, as that may have performance considerations (allocations, etc).
Feature Examples
package main
import (
"fmt""time""github.com/gofiber/fiber/v2""github.com/gofiber/fiber/v2/middleware/logger"
)
typeIceCreamstruct {
Flavorstring`json:"flavor" xml:"flavor"`Colorstring`json:"color" xml:"color"`
}
func (icIceCream) String() string {
returnfmt.Sprintf("Ice Cream!\nFlavor: %v\nColor:%v", ic.Flavor, ic.Color)
}
funcmain() {
app:=fiber.New()
app.Use("/", logger.New())
dessert:=IceCream{"Strawberry", "Pink"}
app.Get("/dessert", func(c*fiber.Ctx) error {
// Since maps are unordered, */* will give us problems, even if// we initialize the map once at startup.returnc.Format(map[string]fiber.Handler{
"application/json": func(c*fiber.Ctx) error { returnc.JSON(dessert) },
"application/xml": func(c*fiber.Ctx) error { returnc.XML(dessert) },
"text/plain": func(c*fiber.Ctx) error { returnc.SendString(dessert.String()) },
"application/vnd.parlor+json": func(c*fiber.Ctx) error {
returnc.JSON(fiber.Map{
"orderDate": time.Now(),
"course": "dessert",
"food": "iceCream",
})
},
})
})
app.Get("/dessert2", func(c*fiber.Ctx) error {
// This is a bit verbose. It might need some beautifying.returnc.Format2(
fiber.AcceptHandler{
MediaType: "application/json",
Handler: func(c*fiber.Ctx) error { returnc.JSON(dessert) },
},
fiber.AcceptHandler{
MediaType: "application/xml",
Handler: func(c*fiber.Ctx) error { returnc.XML(dessert) },
},
fiber.AcceptHandler{
MediaType: "text/plain",
Handler: func(c*fiber.Ctx) error { returnc.SendString(dessert.String()) },
},
fiber.AcceptHandler{
MediaType: "application/vnd.parlor+json",
Handler: func(c*fiber.Ctx) error {
returnc.JSON(fiber.Map{
"orderDate": time.Now(),
"course": "dessert",
"food": "iceCream",
})
},
},
)
})
app.Get("/dessert3", func(c*fiber.Ctx) error {
// Previous c.Format functionality.returnc.AutoFormat(dessert)
})
app.Listen(":3000")
}
Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord
Feature Proposal Description
The current API for
Ctx.Format
does not align withres.format
from Express. While they both perform content negotiation, the usage is different (see below for a comparison). This may be confusing for Gophers coming from Express who expect to be able to add their own handlers.I propose reworking
Ctx.Format
to take a mapping of accept types to handlers. We can move the existingCtx.Format
functionality to a separate method (e.g.,Ctx.AutoFormat
)Alignment with Express API
In Express,
res.format
is used to perform content negotiation and call a different handler based on the result. The handlers are fully user-defined aside from the default handler which will send a 406 HTML response.From https://expressjs.com/en/api.html#res.format
Fiber's Ctx.Format has automatic handlers for a fixed set of Accept headers. The usage is different; it hides details of the request's Accept header and the outgoing Content Type from the implementer.
See below for proposed syntax.
HTTP RFC Standards Compliance
RFC-9110 does not specify how servers should reply to requests with respect to content - it simply gives various suggestions and algorithms.
res.format
follows the proactive negotiation algorithm.API Stability
The new
Ctx.Format
should be in line withres.format
, meaning it should have a stable API. The main risk for API stability is the data structure in which the handlers are passed, as that may have performance considerations (allocations, etc).Feature Examples
Checklist:
The text was updated successfully, but these errors were encountered: