datasift / served

A C++11 RESTful web server library

https://github.com/datasift/served

Install

To install this package, run the following command in your project directory.

buckaroo install datasift/served

Learn More

Read Me

Served

Served Logo

Build Status

Overview

Served is a C++ library for building high performance RESTful web servers.

Served builds upon Boost.ASIO to provide a simple API for developers to create HTTP services in C++.

Features:

  • [x] HTTP 1.1 compatible request parser
  • [x] Middleware / plug-ins
  • [x] Flexible handler API
  • [x] Cross-platform compatible

Installation

Requirements

Building

$ git clone git@github.com:datasift/served.git
$ mkdir served.build && cd served.build
$ cmake ../served && make

Or, using bazel:

$ git clone git@github.com:datasift/served.git
$ cd served
$ bazel build :served
$ bazel test :served-test

Getting Started

The most basic example of creating a server and handling a HTTP GET for the path /hello:

#include <served/served.hpp>

int main(int argc, char const* argv[]) {
    // Create a multiplexer for handling requests
    served::multiplexer mux;

    // GET /hello
    mux.handle("/hello")
        .get([](served::response & res, const served::request & req) {
            res << "Hello world!";
        });

    // Create the server and run with 10 handler threads.
    served::net::server server("127.0.0.1", "8080", mux);
    server.run(10);

    return (EXIT_SUCCESS);
}

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/hello -ivh

You can also use named path variables for REST parameters:

mux.handle("/users/{id}")
    .get([](served::response & res, const served::request & req) {
        res << "User: " << req.params["id"];
    });

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/users/dave -ivh

If you need to be more specific, you can specify a pattern to use to validate the parameter:

mux.handle("/users/{id:\\d+}")
    .get([](served::response & res, const served::request & req) {
        res << "id: " << req.params["id"];
    });

To test the above example, you could run the following command from a terminal:

$ curl http://localhost:8080/users/1 -ivh

Method handlers can have arbitrary complexity:

mux.handle("/users/{id:\\d+}/{property}/{value:[a-zA-Z]+")
    .get([](served::response & res, const served::request & req) {
        // handler logic
    });

If you want to automatically log requests, you could use a plugin (or make your own):

#include <served/plugins.hpp>
// ...
mux.use_after(served::plugin::access_log);

You can also access the other elements of the request, including headers and components of the URI:

mux.handle("/posts/{id:\\d+}")
    .post([](served::response & res, const served::request & req) {
        if (req.header("Content-Type") != "application/json") {
            served::response::stock_reply(400, res);
            return;
        }
        res << req.url().fragment();
    });

Compile Options

OptionPurpose
SERVED_BUILD_SHAREDBuild shared library
SERVED_BUILD_STATICBuild static library
SERVED_BUILD_TESTSBuild unit test suite
SERVED_BUILD_EXAMPLESBuild bundled examples
SERVED_BUILD_DEBBuild DEB package (note: you must also have dpkg installed)
SERVED_BUILD_RPMBuild RPM package (note: you must also have rpmbuild installed)

System Compatibility

OSCompilerStatus
LinuxGCC 4.8Working
OSXClang 3.5Working

TODO

  • Chunked encoding support

Contributing

Pull requests are welcome.

Authors

Copyright

See LICENSE.md document