Luddite is a golang package that provides a micro-framework for RESTful web services. It is built around extensible, pluggable middleware layers and includes a flexible resource abstraction that makes it easy to implement services that comply with the Orion REST API Standards.
To run the example service:
$ cd example
$ go build .
$ ./example -c config.yaml
The basic request handling built into luddite
combines CORS, tracing, logging,
metrics, profiling, and recovery actions.
Tracing generates a unique request id and optionally records trace spans to a file or pluggable backend. The framework currently uses the [OpenTracing] (https://github.com/opentracing/opentracing-go) package.
Logging is based on logrus. A service log is established for general use. An access log is maintained separately. Both use structured JSON logging.
Prometheus metrics provide basic request/response
stats. By default, the metrics endpoint is served on /metrics
.
The standard net/http/pprof profiling
handlers may be optionally enabled. These are served on /debug/pprof
.
Recovery handles panics that occur in resource handlers and optionally includes
stack traces in 500
responses.
Currently, luddite
registers two middleware handlers for each service:
-
Bottom: Handles CORS
OPTION
requests. Establishes request context, handles tracing, logging and recovery. -
Negotiation: Performs JSON (default) and other content negotiation based on HTTP requests'
Accept
headers. -
Version: Performs API version selection and enforces the service's min/max supported version constraints. Makes the selected API version available to resource handlers as part of the request context.
-
Top: Dispatches requests using the service's global router or API version-specific routers. The global router is given priority.
Implementations are free to register their own additional middleware handlers in addition to these four. Custom middleware handlers are inserted just below the top middleware.
Generally, each resource falls into one of two categories.
- Collection: Supports
GET
,POST
,PUT
, andDELETE
. - Singleton: Supports
GET
andPUT
.
The framework defines several interfaces that establish its resource abstraction. For collection-style resources:
CollectionLister
returns all elements in response toGET /resource
.CollectionCounter
returns a count of its elements in response toGET /resource/all/count
.CollectionGetter
returns a specific element in response toGET /resource/:id
.CollectionCreator
creates a new element in response toPOST /resource
.CollectionUpdater
updates a specific element in response toPUT /resource/:id
.CollectionDeleter
deletes a specific element in response toDELETE /resource/:id
. It may also optionally delete the entire collection in response toDELETE /resource
CollectionActioner
executes an action in response toPOST /resource/:id/:action
.
And for singleton-style resources:
SingletonGetter
returns a response toGET /resource
.SingletonUpdater
is updated in response toPUT /resource
.SingletonActioner
executes an action in response toPOST /resource/:action
.
Routes are automatically created for resource handler types that implement these
interfaces. However, since luddite
is a framework, implementations retain
substantial flexibility to register their own routes if these are not
sufficient.
The framework allows implementations to support multiple API versions simultaneously. In addition to API version selection via middleware, the framework also allows for version-specific resource registration.
Typically, implementations define a separate resource handler type for each API version. The routes for each type are registered in a version-specific router. Since route lookup occurs after version negotiation, each router is free to handle requests without further consideration of API version.