Niven is a C++17 library that simplifies the task of creating a REST-based API.
It is inspired by the C# Nancy framework and uses similar techniques for declaring routes and responses.
Niven is designed to be self-hosted and is built upon the libmicrohttpd C library.
class SimpleModule : public Module
{
public:
SimpleModule()
{
Get["/"] = [](auto) {
return "The moon's a balloon";
};
}
};
REGISTER_MODULE(SimpleModule)
Routes can contain literal segments as well as named captures.
Get["/person/{id}"] = [](auto &c) {
return "Someone with an ID of " + c["id"];
};
A number of response types are supported simply by returning the appropriate value.
As seen above you can return a string which will result in a "text/plain" content
type and a status of Http::Ok
. Other responses include:
- HTTP status code, e.g.
return Http::Unauthorized;
- A path which will return a file on disk if it exists,
e.g.
return std::filesystem::path(filename);
- Entity or tree which will be automatically serialised to JSON,
e.g.
return tree {{ "name", "Test" }};
Additionally, by explicitly returning a Response object you can manipulate the headers and cookies using a fluent syntax.
Get["/"] = [](auto) {
return Response()
.WithHeader("Content-Type", "application/json")
.WithCookie({ "niven-test", "chocolate chip", DateTime::Now().AddSeconds(30) });
};
Niven contains a basic dependency container implementation.
Register a singleton with the host by passing in a shared_ptr:
host.Register<MyType>(std::make_shared<MyDerivedType>());
Register a concrete class type with the host to be constructed each time it is resolved with the given parameters:
host.Register<MyType, MyDerivedType>(param1, param2...);
Within a request handler the dependency can be resolved via the context:
Get["/{key}"] = [](Context &c) {
return c.Resolve<MyType>()->Get(c["key"]);
};
Niven uses libentity for dealing with request/response JSON.
If you return either an object derived from ent::entity
or an ent::tree
as a response it will be automatically serialised as a JSON string and the response
content type set to "application/json".
Incoming JSON can be bound to an object, for example
Post["/bind"] = [](Context &c) {
return "The name is: " + c.Bind<MyEntity>().name;
};
Please take a look in the src/examples
directory to see how to set
up the host and in include/examples
for some simple commented modules.
- libmicrohttpd - the HTTP host back-end.
- libgcrypt - for hashing and SSL.
- libemergent - type registration, file paths, datetime helper, logging, string helpers.
- libentity - entity serialisation/deserialisation, trees.
A modern compiler that supports C++17 such as clang and premake v5.0.
$ sudo apt-get install libmicrohttpd-dev libgcrypt20-dev
Ensure that the headers for libemergent and libentity can be found on the standard
paths (for example /usr/local/include
).
$ premake5 gmake
$ make
To build the examples:
$ cd src/examples
$ premake5 gmake
$ make
When building an application with niven you must link against libniven and pthread.