Problem details for HTTP APIs per RFC-9457 standard.
This module provides the Problem
struct which can be used to represent a problem
in HTTP APIs. It implements the RFC-9457 standard.
It supports serializing and deserializing the Problem
struct to and from JSON.
go-problem
module provides an easy way to send the Problem
struct as a response to the client.
package middleware
import (
"net/http"
"github.com/kodeart/go-problem"
)
func NotFoundHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
p := problem.Problem{
Status: http.StatusNotFound,
Detail: "No such API route",
Title: "Route Not Found",
Instance: r.URL.Path,
}
p.JSON(w)
}
}
// or with helper methods
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
problem.New().
WithStatus(http.StatusNotFound).
WithDetail("No such API route").
WithTitle("Route Not Found").
WithInstance(r.URL.Path).
JSON(w)
}
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/kodeart/go-problem"
)
func main() {
mux := chi.NewRouter()
mux.NotFound(middleware.NotFoundHandler)
...
mux.Get("/", func(w http.ResponseWriter, r *http.Request) {
problem.New().
WithStatus(http.StatusServiceUnavailable).
WithExtension("maintenance", true).
WithExtension("version", "1.0.0").
JSON(w)
})
}
...
p := problem.New().
WithStatus(http.StatusUnprocessableEntity).
WithType("https://example.com/probs/out-of-credit").
WithTitle("You do not have enough credit.").
WithDetail("Your current balance is 30, but that costs 50.").
WithInstance("/account/12345/msgs/abc").
WithExtension("balance", 30).
WithExtension("accounts", []string{
"/account/12345",
"/account/67890",
})
}
p := problem.Problem{
Status: http.StatusUnprocessableEntity,
Type: "https://example.com/probs/out-of-credit",
Title: "You do not have enough credit.",
Detail: "Your current balance is 30, but that costs 50.",
Instance: "/account/12345/msgs/abc",
Extensions: map[string]interface{}{
"balance": 30,
"accounts": []string{
"/account/12345",
"/account/67890",
},
},
}
This project is licensed under the MIT License - see the LICENSE file for details.