Topper is a lightweight framework for defining RESTful services in C++. It provides a library of event-driven IO, logging, and metrics collection that allow developers to focus on defining services instead of the low-level details of writing HTTP servers.
Topper is a work in progress; refer to the task list for details & usage caveats.
A minimal Topper server requires only a few lines of code:
#include "resource.h"
#include "response.h"
#include "server.h"
using topper::Resource;
using topper::Server;
class HelloResource : public Resource {
public:
HelloResource() : Resource("/hello/{user}") { }
Response get(StringParameter const& param) const {
return Response(HttpCode::OK, MediaType::TEXT_PLAIN,
std::string("Hello, ") + param.value + std::string("\n"));
}
}
int main(void) {
HelloResource hello;
Server server("127.0.0.1", 8080);
server.registerResource(&hello);
server.start();
// Wait for interruption
server.wait();
return 0;
}
# Resolve transitive dependencies
git submodule update --init --recursive
# Then build
mkdir build
cd build
cmake ..
make
Resources can define path parameter templates that are provided to the
request handler. In the example above, the server defines an endpoint
/hello/{user}
with a single path parameter. Requests to that endpoint will
have the last path component translated to an input parameter to the relevant
handler method; for example, requests to /hello/visitor
will result in
invocation of HelloResource::get
with a "visitor" parameter.
See the hello server for more examples of path parameter usage.
In progress.
Besides path parameters, Topper resources can access parameters passed in the
URI query component, as defined in RFC
3986. These are made
available to the request handler when a QueryParams
argument is present in
the handler signature, e.g.
Response get(QueryParams const& params)
Parameters may have multiple values, which are returned in a std::vector
from the QueryParams::get
method.
Likewise, parameters passed as application/x-www-form-urlencoded
in a POST
message are available as an optional PostParams
argument in the handler
method.
Headers in an HTTP request are available to resources as an optional header parameters argument in the resource handler signature, e.g.
Response get(HeaderParams const& headers)
Header values are returned from the get(...)
method, which performs
case-sensitive matching on header values. Header parameters can be combined
with all other parameter types in a resource handler method; for example,
the following is a valid handler for a resource with one path parameter:
Response post(StringParam const& pathparam, HeaderParams const& headers,
PostParams const& postparams)
In progress.
Topper servers can be configured to expose an administration interface on a
separate ip, port
tuple. This interface includes the following endpoints:
/ping
/metrics
The /ping
endpoint responds to GET
requests with a document containing
pong
, and can be used to check whether the server is running.
The /metrics
endpoint publishes server metrics in JSON format:
# Admin port 40967
$ curl http://127.0.0.1:40967/metrics |python -mjson.tool
{
"counters": {},
"timers": {
"topper.resource.dispatch": {
"count": 14,
"m15_rate": 0.2110435060583438,
"m1_rate": 0.3523419255254859,
"m5_rate": 0.23273016404633015,
"max": 0.003941,
"mean": 0.0003459285714285714,
"min": 2.3e-05,
"p50": 2.55e-05,
"p75": 8.274999999999999e-05,
"p95": 0.003941,
"p99": 0.003941,
"p999": 0.003941,
"stdev": 0.0010411176686619047
}
}
}
Runtime application metrics are provided by the ccmetrics library; refer to the library documentation for details.
Copyright © 2015 Nathan Rosenblum flander@gmail.com
Licensed under the MIT License.
This project was inspired by the author's pleasant experience using Dropwizard to quickly bring up small, RESTful services in Java.
Topper's path component parsing rules and interfaces ow much to Jersey, the reference implementation of JAX-RS.