# README
scroll
Scroll is a lightweight library for building Go HTTP services at Mailgun. It is built on top of mux and adds:
- Service Discovery
- Graceful Shutdown
- Configurable Logging
- Request Metrics
Scroll is a work in progress. Use at your own risk.
Installation
go get github.com/mailgun/scroll
Getting Started
Building an application with Scroll is simple. Here's a server that listens for GET or POST requests to http://0.0.0.0:8080/resources/{resourceID}
and echoes back the resource ID provided in the URL.
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"github.com/mailgun/holster/etcdutil"
"github.com/mailgun/metrics"
"github.com/mailgun/scroll"
"github.com/mailgun/scroll/vulcand"
)
const (
APPNAME = "example"
)
func Example() {
// These environment variables provided by the environment,
// we set them here to only to illustrate how `NewEtcdConfig()`
// uses the environment to create a new etcd config
os.Setenv("ETCD3_USER", "root")
os.Setenv("ETCD3_PASSWORD", "rootpw")
os.Setenv("ETCD3_ENDPOINT", "localhost:2379")
os.Setenv("ETCD3_SKIP_VERIFY", "true")
// If this is set to anything but empty string "", scroll will attempt
// to retrieve the applications config from '/mailgun/configs/{env}/APPNAME'
// and fill in the PublicAPI, ProtectedAPI, etc.. fields from that config
os.Setenv("MG_ENV", "")
// Create a new etc config from available environment variables
cfg, err := etcdutil.NewEtcdConfig(nil)
if err != nil {
fmt.Fprintf(os.Stderr, "while creating etcd config: %s\n", err)
return
}
hostname, err := os.Hostname()
if err != nil {
fmt.Fprintf(os.Stderr, "while obtaining hostname: %s\n", err)
return
}
// Send metrics to statsd @ localhost
mc, err := metrics.NewWithOptions("localhost:8125",
fmt.Sprintf("%s.%v", APPNAME, strings.Replace(hostname, ".", "_", -1)),
metrics.Options{UseBuffering: true, FlushPeriod: time.Second})
if err != nil {
fmt.Fprintf(os.Stderr, "while initializing metrics: %s\n", err)
return
}
app, err := scroll.NewAppWithConfig(scroll.AppConfig{
Vulcand: &vulcand.Config{Etcd: cfg},
PublicAPIURL: "http://api.mailgun.net:1212",
ProtectedAPIURL: "http://localhost:1212",
PublicAPIHost: "api.mailgun.net",
ProtectedAPIHost: "localhost",
Name: APPNAME,
ListenPort: 1212,
Client: mc,
})
if err != nil {
fmt.Fprintf(os.Stderr, "while initializing scroll: %s\n", err)
return
}
app.AddHandler(
scroll.Spec{
Methods: []string{"GET"},
Paths: []string{"/hello"},
Handler: func(w http.ResponseWriter, r *http.Request, params map[string]string) (interface{}, error) {
return scroll.Response{"message": "Hello World"}, nil
},
},
)
// Start serving requests
app.Run()
# Functions
Given a map of parameters url decode each parameter.
GetDurationField retrieves a request field as a time.Duration, which is not allowed to be negative.
Retrieve a request field as a float.
Retrieve a POST request field as an integer.
Retrieve fields with the same name as an array of strings.
Retrieve a POST request field as a string.
Retrieves requested field as a string, allowSet provides input sanitization.
Retrieve a POST request field as a string.
Helper method to retrieve an optional timestamp from POST request field.
GetVarSafe is a helper function that returns the requested variable from URI with allowSet providing input sanitization.
No description provided by the author
Wraps the provided handler function encapsulating boilerplate code so handlers do not have to implement it themselves: parsing a request's form, formatting a proper JSON response, emitting the request stats, etc.
Make a handler out of HandlerWithBodyFunc, just like regular MakeHandler function.
No description provided by the author
No description provided by the author
Create a new app.
Create a new app with the provided configuration.
Reply with the provided HTTP response and status code.
ReplyError converts registered error into HTTP response code and writes it back.
ReplyInternalError logs the error message and replies with a 500 status code.
# Constants
Suggested result set limit for APIs that may return many entries (e.g.
Suggested max allowed amount of entries that batch APIs can accept (e.g.
Suggested max allowed result set limit for APIs that may return many entries (e.g.
No description provided by the author
No description provided by the author
# Variables
When Handler or HandlerWithBody is used, this function will be called after every request with a log message.
# Structs
AllowSetBytes allows the definition of a set of safe allowed ASCII characters.
AllowSetStrings allows the definition of a set of safe allowed strings.
Represents an app.
Represents a configuration object an app is created with.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
This is a separate struct because JSON unmarshal() throws errors on the functions in AppConfig.Client.
No description provided by the author
No description provided by the author
No description provided by the author
Represents handler's specification.
No description provided by the author
# Interfaces
The AllowSet interface is implemented to detect if input is safe or not.
# Type aliases
Defines the signature of a handler function that can be registered by an app.
Defines a signature of a handler function, just like HandlerFunc.
Response objects that apps' handlers are advised to return.
No description provided by the author