A lightweight Go library for parsing HTTP Accept headers and selecting the
most suitable Content-Type.
Documents followed for Accept http request header:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
- https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types
- https://www.iana.org/assignments/media-types/media-types.xhtml#application
- https://developer.mozilla.org/en-US/docs/Glossary/Quality_values
go get -u github.com/vigo/acceptBy default, unless otherwise specified, the fallback content type is always
set to application/json. If desired, you can customize the fallback value
using WithDefaultMediaType method. Also, if request Accept header is */*,
library matches first supported media type too.
// your server supports: application/json and text/html
contentNegotiator := accept.New(
accept.WithSupportedMediaTypes("application/json", "text/html"),
)
contentNegotiator := accept.New(
accept.WithSupportedMediaTypes("application/json", "text/html"),
accept.WithDefaultMediaType("text/plain"),
)
// in your http handler
acceptHeader := r.Header.Get("Accept")
contentType := cn.Negotiate(acceptHeader)Full example, your server supports: application/json, text/html and
text/plain and for unmatched Accept header, will use text/plain as
default fallback value.
# main.go
package main
import (
"encoding/json"
"log"
"net/http"
"github.com/vigo/accept"
)
func handlerFunc(cn *accept.ContentNegotiation) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
acceptHeader := r.Header.Get("Accept")
contentType := cn.Negotiate(acceptHeader)
w.Header().Set("Content-Type", contentType)
switch contentType {
case "application/json":
response := map[string]string{"message": "OK"}
if err := json.NewEncoder(w).Encode(response); err != nil {
http.Error(w, "failed to encode JSON", http.StatusInternalServerError)
}
case "text/html":
_, _ = w.Write([]byte("<p>\n\t<span>message<span>\n\t<pre>OK</pre>\n</p>\n"))
default:
_, _ = w.Write([]byte("message: OK\n"))
}
}
}
func main() {
contentNegotiator := accept.New(
accept.WithSupportedMediaTypes("application/json", "text/html", "text/plain"),
accept.WithDefaultMediaType("text/plain"),
)
log.Println("starting server at :8080")
http.HandleFunc("/", handlerFunc(contentNegotiator))
log.Fatal(http.ListenAndServe(":8080", nil))
}Run the server:
go run main.goTest the requests:
curl localhost:8080 -H 'Accept: text/html'
curl localhost:8080 -H 'Accept: text/plain'
curl localhost:8080 -H 'Accept: text/markdown' # fallback to "text/plain"
curl localhost:8080 -H 'Accept: application/json'
curl localhost:8080 # curl sends */*, first match is "application/json"rake -T
rake coverage # show test coverage
rake test # run testThis project is licensed under MIT (MIT)
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.