A simple way of creating efficient HTTP APIs in golang using conventions over configuration.
To install govalin run:
go get -u github.com/pkkummermo/govalinfunc main() {
govalin.New().
Get("/test", func(call *govalin.Call) {
call.Text("Hello world")
}).
Start(7070)
}Govalin ships a test harness, govalintest, for testing your application over real HTTP. Hand it your own app — built by your own constructor, with your config, plugins and routes — and it starts it on an OS-assigned port, waits for it to be ready, and shuts it down when the test finishes:
import (
"testing"
"github.com/pkkummermo/govalin/govalintest"
)
func TestMyAPI(t *testing.T) {
govalintest.Test(t, myapp.New(), func(client *govalintest.Client) {
if body := client.Get("/health"); body != "ok" {
t.Errorf("expected ok, got %q", body)
}
})
}A few things to know:
- Failures fail the calling test (
t.Fatalf), never the test process. - The body-returning verbs (
Get,Post, ...) return the body regardless of status code, so you can assert on error responses. Use the*Responsevariants (GetResponse, ...) to assert on status codes and headers. Post,PutandPatchsendstring,[]byteandio.Readerbodies as-is; any other value is JSON-encoded withContent-Type: application/json.- For anything custom (headers, auth, exotic verbs), build an
*http.Requestwith a relative path and pass it toclient.Do(...), or grab the underlying client withclient.HTTP(). client.Websocket(path)connects a websocket to your app.- Harness knobs live in
govalintest.TestWithOptions(t, app, govalintest.Options{...}, fn)— the zero value always means sane defaults.
I love how fast and efficient go is. What I don't like, is how it doesn't create an easy way of creating HTTP APIs. Govalin focuses on pleasing those who want to create APIs without too much hassle, with a lean simple API.
Inspired by simple libraries and frameworks such as Javalin, I wanted to see if we could port the simplicity to golang.