View the Project on GitHub DEGoodmanWilson/luna
A static webserver and API framework in modern C++, Luna is designed to serve low latency, high throughput static web applications backed by an API, with an easy to use interface. Yeah, C++. Come at me. Luna is fast, and easy to program. You’ll never go back to Node.js.
Luna’s core philosophy is that it should be easy to use correctly and difficult to use incorrectly.
An excellent question. The first and most obvious answer is because C++ is fast. Also, compiled, statically-typed languages will catch many classes of errors before they make it into deployment, making your web applications and APIs more robust. Lastly, to be completely honest, C++ is fun. Or so I think anyway.
You have a static website or single-page app that needs a robust, responsive API to back it. C++ is your friend, my friend.
You are writing a web application, and you want it as close to the bare metal as possible to keep response latency to the absolute minimum. You’re using modern C++ for its memory safety, and you’d like a web framework that does the same.
You are writing a server or daemon in C++ (because C++ is awesome), and your services needs to provide a lightweight HTTP server to communicate with other web clients. You’d use libmicrohttpd
, which is also super-awesome except for that idiomatically C API. Luna is an idiomatically C++ wrapper for libmicrohttpd
that leans on modern C++ programming concepts.
Yeah, C++ sounds scary, but it isn’t. Scroll down and look at that example. Do it. That’s not worse than Node.js is it? Indeed, it’s better, because unlike Node, C++ wears its semantics on its sleeve: There are no side effects, everything is explicit (no hoisting! scopes are explicit, no trying to understand the contents of this
!), and most errors will be caught at compile time, so you know you are deploying code free from syntax errors.
You speak C++ already? Why should you choose Luna?
HTTP server creation, start, shut down, and deletion are all handled behind the scenes with the magic of RAII. Starting a server is automatic with instantiating a server
object, and allowing your server
object to fall out of scope is all that is needed to cleanly shut it down. There is nothing else for you to keep track of, or allocate.
Adding endpoints to your server is likewise meant to be simple. Nominate an endpoint with a string or regex and an HTTP verb, and pass in a lambda or other std::functional
-compatible object (function pointers, bound class member functions), and return a string containing the desired response body. This kind of flexibility means Luna works with heavily object-oriented code—or more procedural or even functional programming styles, as you prefer.
But don’t take my word for it. Here is some code for serving a simple JSON snippet from a single endpoint. You can find and run this example in examples/intro.cpp
#include <string>
#include <iostream>
#include <luna/luna.h>
using namespace luna;
int main(void)
{
// create the server object
server server;
// set up an endpoint that serves some JSON on /endpoint
auto api = server.create_router("/");
api->set_mime_type("application/json"); //the default is "text/html; charset=UTF-8"
// Handle GET requests to "localhost:8080/endpoint"
// Respond with a tiny bit of fun JSON
api->handle_request(request_method::GET, "/endpoint",
[](auto request) -> response
{
return {"{\"made_it\": true}"};
});
//start a server on port 8080;
std::cout << "curl -v http://localhost:8080/endpoint" << std::endl;
server.start(8080);
}
A C++14 capable compiler (tested against gcc 4.9, clang 3.6), CMake 2.8. Conan for installing dependencies.
This library has only begun, and is a constant state of flux.