REST-oriented API application kit for modern C++.
api_app provides a JSON-first API foundation built on top of vix/web_app, which itself builds on vix/app.
Header-only. Layered. Deterministic.
https://vixcpp.com/registry/pkg/vix/api_app
Every API backend needs:
- Structured JSON responses
- Consistent error payloads
- Proper HTTP status handling
- Exception-to-response mapping
- Clean separation between transport and business logic
Most C++ web backends either:
- Manually build JSON strings everywhere
- Return inconsistent error formats
- Mix status handling with core logic
- Lack structured exception mapping
api_app provides:
- Standard JSON response helpers (
ok_json,created_json, etc.) - Standardized error format
ApiExceptionfor controlled error flow- Automatic exception → JSON error mapping
- Clean layering over
web_app
No reflection. No required JSON library. No middleware system forced on you.
Just a structured API foundation.
api_app depends on:
vix/web_app- (transitively)
vix/app
Layered architecture:
vix/app
↑
vix/web_app
↑
vix/api_app
This ensures:
- Clear module boundaries
- No circular dependencies
- Stable foundation
- Composable runtime layers
When installed via Vix Registry, dependencies are installed automatically.
vix add vix/api_app
vix depsThis will automatically install:
vix/web_appvix/app
git clone https://github.com/vixcpp/api_app.gitAdd the include/ directory and ensure web_app (and app) are available.
#include <api_app/api_app.hpp>
using namespace vix::web_app;
using namespace vix::api_app;
class MyApi : public ApiApplication
{
protected:
void serve_once() override
{
Request req;
req.method = HttpMethod::Get;
req.path = "/health";
auto res = dispatch_api(req);
stop();
}
};
int main()
{
MyApi app;
app.router().get("/health", [](const Request&) {
return ApiApplication::ok_json("{\"status\":\"ok\"}");
});
app.run();
}Error responses follow this JSON shape:
{
"error": {
"code": "bad_request",
"message": "Human readable message"
}
}You can throw ApiException inside handlers:
app.router().get("/users", [](const Request&) -> Response {
throw ApiException("bad_request", "missing id parameter", 400);
});dispatch_api() automatically converts it to a JSON error response.
ApiApplication::ok_json("{...}");
ApiApplication::created_json("{...}");
ApiApplication::no_content();
ApiApplication::bad_request("message");
ApiApplication::unauthorized();
ApiApplication::forbidden();
ApiApplication::not_found();
ApiApplication::conflict();
ApiApplication::unprocessable();
ApiApplication::internal_error();All JSON helpers automatically set:
content-type: application/json
dispatch_api() wraps routing dispatch and converts:
ApiException→ structured JSON errorstd::exception→ 500internal_error- unknown exceptions → 500
internal_error
This keeps handler code clean and explicit.
Types:
vix::api_app::ApiApplicationvix::api_app::ApiExceptionvix::api_app::ApiError
Methods:
ApiApplication::dispatch_api()ApiApplication::ok_json()ApiApplication::bad_request()ApiApplication::internal_error()
api_app focuses on:
- Deterministic API behavior
- Explicit status handling
- Consistent JSON error structure
- Minimal abstraction
- Clean layering over transport
It does not provide:
- Automatic JSON serialization
- ORM integration
- Authentication middleware
- Validation framework
Those belong in higher-level modules or user space.
- Routing remains O(1) average (hash lookup from
web_app). - JSON helpers are O(n) relative to body size.
- Exception mapping is constant time.
Run:
vix build
vix testTests verify:
- JSON helpers
- Error mapping
ApiExceptionbehavior- 500 fallback
- Integration with lifecycle
MIT License
Copyright (c) Gaspard Kirira