Core
vix::core is the native application layer of Vix.
Use it when you want to build HTTP applications with routes, handlers, middleware, request and response objects, templates, static files, configuration, TLS, and server lifecycle management.
Public header
#include <vix.hpp>You can also include the core header directly:
#include <vix/core.hpp>What Core provides
Vix Core connects the main pieces needed to build a native Vix web application.
It includes:
vix::Appfor application setup and server lifecycle- HTTP routing with
GET,POST,PUT,PATCH,DELETE,HEAD, andOPTIONS - route parameters such as
/users/{id} - middleware and protected route prefixes
- native
RequestandResponseobjects - JSON, text, file, redirect, and template responses
- static file mounting
- HTTP sessions and transports
- optional TLS support
- configuration loading
- an HTTP server built on
vix::async - a runtime executor built on
vix::runtime
Basic idea
Most Core applications start with an App.
vix::App app;Then routes are registered on the app.
app.get("/", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.text("Hello from Vix");
});2
3
4
5
6
Finally, the app is started.
app.run(8080);Minimal HTTP server
#include <vix.hpp>
int main()
{
vix::App app;
app.get("/", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.text("Hello from Vix");
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Run:
vix run main.cppThen open:
http://localhost:8080Expected response:
Hello from VixJSON response
Use res.json(...) to send JSON.
#include <vix.hpp>
int main()
{
vix::App app;
app.get("/api/status", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.json({
"status", "ok",
"server", "Vix.cpp"
});
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Example response:
{
"status": "ok",
"server": "Vix.cpp"
}2
3
4
Request and response
Core exposes two common aliases for application code:
vix::Request
vix::Response2
vix::Request gives access to the incoming request.
req.method();
req.path();
req.target();
req.body();
req.header("Content-Type");
req.query_value("page");
req.param("id");2
3
4
5
6
7
vix::Response is a response helper built around the native Vix response object.
res.status(200);
res.text("OK");
res.json({"ok", true});
res.redirect("/login");
res.file("public/index.html");2
3
4
5
Route parameters
Routes can contain named parameters.
#include <vix.hpp>
int main()
{
vix::App app;
app.get("/users/{id}", [](vix::Request &req, vix::Response &res)
{
const std::string id = req.param("id");
res.json({
"user_id", id
});
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Request:
GET /users/42Example response:
{
"user_id": "42"
}2
3
Middleware
Middleware can run before a route handler.
#include <vix.hpp>
int main()
{
vix::App app;
app.use([](vix::Request &req, vix::Response &res, vix::App::Next next)
{
(void)res;
vix::print("request:", req.method(), req.path());
next();
});
app.get("/", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.text("home");
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Middleware can also be attached to a prefix.
app.use("/admin", [](vix::Request &req, vix::Response &res, vix::App::Next next)
{
(void)req;
const bool allowed = true;
if (!allowed)
{
res.status(403).json({"error", "forbidden"});
return;
}
next();
});2
3
4
5
6
7
8
9
10
11
12
13
14
Route groups
Use groups to organize routes under a common prefix.
#include <vix.hpp>
int main()
{
vix::App app;
app.group("/api", [](auto &api)
{
api.get("/status", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.json({"status", "ok"});
});
api.get("/version", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.json({"version", "1.0.0"});
});
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
The routes become:
GET /api/status
GET /api/version2
Static files
Use static_dir to mount a directory.
#include <vix.hpp>
int main()
{
vix::App app;
app.static_dir("public", "/");
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
Example mapping:
GET /style.csscan serve:
public/style.cssTemplates
Use templates(...) to configure a template directory.
#include <vix.hpp>
int main()
{
vix::App app;
app.templates("views");
app.get("/", [](vix::Request &req, vix::Response &res)
{
(void)req;
vix::tmpl::Context ctx;
ctx.set("title", "Home");
res.render("index.html", ctx);
});
app.run(8080);
return 0;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Core architecture
Core is built as a set of layers.
App
-> Router
-> HTTPServer
-> Session
-> Transport
-> RuntimeExecutor2
3
4
5
6
The simplified request flow is:
TCP connection
-> HTTPServer
-> Session
-> Transport
-> Request parsing
-> Router
-> RequestHandler
-> user handler
-> Response
-> Transport write2
3
4
5
6
7
8
9
10
Core and vix::async
Core uses vix::async for I/O work.
That includes:
- accepting TCP connections
- reading request bytes
- writing response bytes
- running session coroutines
- timers and cancellation
- spawning async tasks on the I/O context
The HTTP server owns a native async io_context and runs it on I/O threads.
Core and vix::runtime
Core uses vix::runtime through RuntimeExecutor.
The executor is responsible for scheduling application work on runtime workers.
This keeps the model separated:
vix::async
-> network I/O, timers, coroutine scheduling
vix::runtime
-> internal task execution, workers, scheduling, metrics
vix::core
-> application API, HTTP server, router, sessions, handlers2
3
4
5
6
7
8
Heavy routes
Core can mark some routes as heavy.
app.get_heavy("/reports", [](vix::Request &req, vix::Response &res)
{
(void)req;
res.json({"status", "report generated"});
});2
3
4
5
6
Heavy routes are stored with route metadata so the runtime and router can classify costly work separately when needed.
Configuration
Core uses vix::config::Config for server configuration.
vix::config::Config cfg;
cfg.setServerPort(8080);
vix::App app;
app.run(cfg);2
3
4
5
6
Configuration controls server behavior such as:
- server port
- I/O thread count
- session timeout
- benchmark mode
- WAF settings
- TLS settings
- logging settings
TLS
TLS is optional.
When TLS is disabled, Core accepts plain HTTP connections.
When TLS is enabled and configured, the accepted TCP stream is wrapped in a TLS transport before the HTTP session starts reading requests.
A TLS configuration contains:
vix::server::TlsConfig tls;
tls.enabled = true;
tls.cert_file = "/etc/letsencrypt/live/example.com/fullchain.pem";
tls.key_file = "/etc/letsencrypt/live/example.com/privkey.pem";2
3
4
5
When to use Core
Use Core when you want to build:
- HTTP APIs
- JSON services
- small native web servers
- static websites
- template-rendered apps
- internal tools
- services that need native C++ performance
- applications that should run on top of the Vix runtime model
Next steps
Read the next pages in this module: