Don alternatives and similar packages
Based on the "Web Frameworks" category.
Alternatively, view Don alternatives based on common mentions on social networks and blogs.
-
Gin
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin. -
Gorilla WebSocket
DISCONTINUED. A fast, well-tested and widely used WebSocket implementation for Go. -
Iris
The fastest HTTP/2 Go Web Framework. New, modern and easy to learn. Fast development with Code you control. Unbeatable cost-performance ratio :rocket: -
GoFrame
GoFrame is a modular, powerful, high-performance and enterprise-class application development framework of Golang. -
goa
๐ Goa: Elevate Go API development! ๐ Streamlined design, automatic code generation, and seamless HTTP/gRPC support. โจ -
Faygo
Faygo is a fast and concise Go Web framework that can be used to develop high-performance web app(especially API) with fewer codes. Just define a struct handler, faygo will automatically bind/verify the request parameters and generate the online API doc. -
Huma
A modern, simple, fast & flexible micro framework for building HTTP REST/RPC APIs in Go backed by OpenAPI 3 and JSON Schema. -
GoFr
An opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability. -
go-server-timing
DISCONTINUED. Go (golang) library for creating and consuming HTTP Server-Timing headers
InfluxDB - Purpose built for real-time analytics at any scale.
Do you think we are missing an alternative of Don or a related project?
Popular Comparisons
README
Don - Go API Framework
Don is a fast & simple API framework written in Go. It features a super-simple API and thanks to fasthttp and a custom version of httprouter it's blazing fast and has a low memory footprint.
As Don uses the new Go generics it requires Go 1.18 to work. Also, it's still in beta and the API may yet have breaking changes, so it's not recommended for production use yet.
Contents
Basic Example
package main
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/abemedia/go-don"
_ "github.com/abemedia/go-don/encoding/json" // Enable JSON parsing & rendering.
_ "github.com/abemedia/go-don/encoding/yaml" // Enable YAML parsing & rendering.
)
type GreetRequest struct {
Name string `path:"name"` // Get name from the URL path.
Age int `header:"X-User-Age"` // Get age from HTTP header.
}
type GreetResponse struct {
// Remember to add all the tags for the renderers you enable.
Greeting string `json:"data" yaml:"data"`
}
func Greet(ctx context.Context, req GreetRequest) (*GreetResponse, error) {
if req.Name == "" {
return nil, don.Error(errors.New("missing name"), http.StatusBadRequest)
}
res := &GreetResponse{
Greeting: fmt.Sprintf("Hello %s, you're %d years old.", req.Name, req.Age),
}
return res, nil
}
func Pong(context.Context, don.Empty) (string, error) {
return "pong", nil
}
func main() {
r := don.New(nil)
r.Get("/ping", don.H(Pong)) // Handlers are wrapped with `don.H`.
r.Post("/greet/:name", don.H(Greet))
r.ListenAndServe(":8080")
}
Configuration
Don is configured by passing in the Config
struct to don.New
.
r := don.New(&don.Config{
DefaultEncoding: "application/json",
DisableNoContent: false,
})
DefaultEncoding
Set this to the format you'd like to use if no Content-Type
or Accept
headers are in the
request.
DisableNoContent
If you return nil
from your handler, Don will respond with an empty body and a 204 No Content
status code. Set this to true
to disable that behaviour.
Support multiple formats
Support multiple request & response formats without writing extra parsing or rendering code. The API
uses the Content-Type
and Accept
headers to determine what input and output encoding to use.
You can mix multiple formats, for example if the Content-Type
header is set to application/json
,
however the Accept
header is set to application/x-yaml
, then the request will be parsed as JSON,
and the response will be YAML encoded.
If no Content-Type
or Accept
header is passed the default will be used.
Formats need to be explicitly imported e.g.
import _ "github.com/abemedia/go-don/encoding/yaml"
Currently supported formats
JSON
MIME: application/json
Parses JSON requests & encodes responses as JSON. Use the json
tag in your request & response
structs.
XML
MIME: application/xml
, text/xml
Parses XML requests & encodes responses as XML. Use the xml
tag in your request & response
structs.
YAML
MIME: application/x-yaml
, text/x-yaml
Parses YAML requests & encodes responses as YAML. Use the yaml
tag in your request & response
structs.
Form (input only)
MIME: application/x-www-form-urlencoded
, multipart/form-data
Parses form data requests. Use the form
tag in your request struct.
Text
MIME: text/plain
Parses non-struct requests and encodes non-struct responses e.g. string
, int
, bool
etc.
func MyHandler(ctx context.Context, req int64) (string, error) {
// ...
}
If the request is a struct and the Content-Type
header is set to text/plain
it returns a
415 Unsupported Media Type
error.
MessagePack
MIME: application/x-msgpack
Parses MessagePack requests & encodes responses as MessagePack. Use the msgpack
tag in your
request & response structs.
Adding custom encoding
Adding your own is easy. See [encoding/json/json.go](./blob/master/encoding/json/json.go).
Request parsing
Automatically unmarshals values from headers, URL query, URL path & request body into your request struct.
type MyRequest struct {
// Get from the URL path.
ID int64 `path:"id"`
// Get from the URL query.
Filter string `query:"filter"`
// Get from the JSON, YAML, XML or form body.
Content float64 `form:"bar" json:"bar" yaml:"bar" xml:"bar"`
// Get from the HTTP header.
Lang string `header:"Accept-Language"`
}
Please note that using a pointer as the request type negatively affects performance.
Headers & response codes
Implement the StatusCoder
and Headerer
interfaces to customise headers and response codes.
type MyResponse struct {
Foo string `json:"foo"`
}
// Set a custom HTTP response code.
func (nr *MyResponse) StatusCode() int {
return 201
}
// Add custom headers to the response.
func (nr *MyResponse) Header() http.Header {
header := http.Header{}
header.Set("foo", "bar")
return header
}
Sub-routers
You can create sub-routers using the Group
function:
r := don.New(nil)
sub := r.Group("/api")
sub.Get("/hello")
Middleware
Don uses the standard fasthttp middleware format of
func(fasthttp.RequestHandler) fasthttp.RequestHandler
.
For example:
func loggingMiddleware(next fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
log.Println(string(ctx.RequestURI()))
next(ctx)
})
}
It is registered on a router using Use
e.g.
r := don.New(nil)
r.Post("/", don.H(handler))
r.Use(loggingMiddleware)
Middleware registered on a group only applies to routes in that group and child groups.
r := don.New(nil)
r.Get("/login", don.H(loginHandler))
r.Use(loggingMiddleware) // applied to all routes
api := r.Group("/api")
api.Get("/hello", don.H(helloHandler))
api.Use(authMiddleware) // applied to routes `/api/hello` and `/api/v2/bye`
v2 := api.Group("/v2")
v2.Get("/bye", don.H(byeHandler))
v2.Use(corsMiddleware) // only applied to `/api/v2/bye`
To pass values from the middleware to the handler extend the context e.g.
func myMiddleware(next fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
ctx.SetUserValue(ContextUserKey, "my_user")
next(ctx)
})
}
This can now be accessed in the handler:
user := ctx.Value(ContextUserKey).(string)
Benchmarks
To give you a rough idea of Don's performance, here is a comparison with Gin.
Request Parsing
Don has extremely fast & efficient binding of request data.
Benchmark name | (1) | (2) | (3) | (4) |
---|---|---|---|---|
BenchmarkDon_BindRequest | 2497761 | 469.8 ns/op | 104 B/op | 2 allocs/op |
BenchmarkGin_BindRequest | 296085 | 3970 ns/op | 1273 B/op | 31 allocs/op |
Source: benchmarks/binding_test.go
Serving HTTP Requests
Keep in mind that the majority of time here is actually the HTTP roundtrip.
Benchmark name | (1) | (2) | (3) | (4) |
---|---|---|---|---|
BenchmarkDon_HTTP | 59714 | 19951 ns/op | 73 B/op | 3 allocs/op |
BenchmarkGin_HTTP | 34322 | 34331 ns/op | 2304 B/op | 20 allocs/op |
Source: benchmarks/http_test.go