Documentation

Add Prism to your C++ project, build your first server, then configure and deploy for production, all in one place.

Introduction

Prism is a C++20 web framework for REST APIs, covering routing, middleware, authentication, logging and JSON. The HTTP transport is built on Boost.Asio and C++20 coroutines, providing modern asynchronous request handling.

This page covers installing, configuring and deploying it. For type-by-type signatures, see the API reference.

Prism is pre-1.0. Signatures still change between versions, so pin a release tag rather than tracking main.

The repository also contains Prism API, a blog backend built on the framework, with accounts, posts and comments plus JWT auth, rate limiting, CORS, PostgreSQL persistence and a small web UI. It exists so there is a complete, working app to read rather than only snippets.

Add Prism to your project

Prism is consumed from your CMakeLists.txt. There is nothing to clone or system-install first. CMake fetches and builds it during your own configure step.

CMakeLists.txt
include(FetchContent)
FetchContent_Declare(
    Prism
    GIT_REPOSITORY https://github.com/Segniko/Prism.git
    GIT_TAG        v0.1.0    # pin a tag, main moves
    GIT_SUBMODULES ""
)
FetchContent_MakeAvailable(Prism)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE Prism::Prism)

The only things you need installed are a C++20 compiler, CMake 3.16+ and OpenSSL (for the auth features). nlohmann/json is fetched automatically.

OpenSSL: apt-get install libssl-dev (Linux), brew install openssl (macOS), or vcpkg install openssl (Windows). Don't need auth? Add -DENABLE_OPENSSL=OFF. Prism also ships a vcpkg.json and a conanfile.py.

Quick start

A complete first project is two files. Your main.cpp creates a Server, registers routes and calls start():

main.cpp
#include "Prism.hpp"                     // one header for the whole framework
using namespace Prism;

int main() {
    Server server;                       // defaults: 0.0.0.0:8080, 4 threads
    server.get("/", [](const HttpRequest&) -> boost::asio::awaitable {
        co_return HttpResponse::text("Hello, Prism!");
    });
    server.get("/api/users/:id", [](const HttpRequest& req) -> boost::asio::awaitable {
        Json out;
        out["id"] = req.path_params.at("id");
        co_return HttpResponse::json(out.dump());
    });
    server.start();                      // blocks until stop()
}

Configure, build and run it with CMake. Your server is live on http://localhost:8080:

build & run
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
./build/my_app          # http://localhost:8080

For what each type does, read the API reference. For a full app, clone the repo. The reference API builds as prism-api, and .env.example copied to .env configures it.

Usage examples

Drive the reference API with curl. Registering or logging in returns a JWT you pass back as a Bearer token.

curl
# Register (returns a token)
curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","email":"alice@example.com","password":"a-strong-password"}'

# Create a post (authenticated)
curl -X POST http://localhost:8080/api/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"title":"My First Post","content":"Hello world"}'

# Read posts and a single post with its comments
curl http://localhost:8080/api/posts
curl http://localhost:8080/api/posts/1

Configuration

All settings come from environment variables (a .env file is loaded at startup, and real environment variables win). The important ones:

VariableDefaultNotes
PORT / HOST8080 / 0.0.0.0Listen address
ENVIRONMENTdevelopmentIn production the server refuses to start without a real JWT_SECRET_KEY
JWT_SECRET_KEYnoneToken signing secret. Generate with openssl rand -hex 32
DATABASE_URLnonePostgreSQL connection string (enables the database when set)
ENABLE_DATABASEautoDefaults to true when DATABASE_URL is set
DB_SSLMODEpreferUse require for hosted databases
CORS_ORIGIN*Set to your frontend origin in production
RATE_LIMIT_MAX100Requests per window, per client IP
RATE_LIMIT_WINDOW_SECONDS60Rate-limit window length

In production, set JWT_SECRET_KEY to a strong random value. The server refuses to start without it. Without DATABASE_URL, data is in-memory and lost on every restart.

Connecting to Supabase

  • In the Supabase dashboard go to Project Settings → Database → Connection string and pick the Session pooler variant.
  • Set it as DATABASE_URL (in .env locally, or in the Render dashboard in production).
  • On first start, Prism creates the users, posts, comments and migrations tables and enables row-level security on them.
DATABASE_URL
postgresql://postgres.<project-ref>:<password>@aws-0-<region>.pooler.supabase.com:5432/postgres

Reference API endpoints

These are the HTTP routes of the bundled prism-api demo, not of the framework itself. For the framework's C++ types see the API reference. Authenticated requests send the token in the Authorization: Bearer <token> header.

MethodEndpointAuth
GET/
Web frontend (or API info if missing)
public
GET/api
API info and endpoint list
public
GET/health
Health check incl. database status
public
POST/api/auth/register
Register: {username, email, password}
public
POST/api/auth/login
Login: {username or email, password} → token
public
POST/api/auth/refresh
Exchange a valid token for a fresh one
public
GET/api/auth/me
Current user info
required
POST/api/auth/logout
Revoke the presented token
required
GET/api/posts
List posts (?limit=&offset=)
public
GET/api/posts/:id
Get a post with its comments
public
POST/api/posts
Create a post: {title, content}
required
PUT/api/posts/:id
Update a post
owner/admin
DEL/api/posts/:id
Delete a post
owner/admin
GET/api/posts/:id/comments
List comments
public
POST/api/posts/:id/comments
Add a comment: {content} (author from token)
required

Project structure

lib/
Prism/
├── ConfigAPI/
│   ├── include/      # Public headers, the part you consume
│   ├── src/          # Implementations + main.cpp (the reference API)
│   ├── third_party/  # Vendored dependencies
│   └── examples/     # Example programs (-DBUILD_EXAMPLES=ON)
├── website/          # This documentation site (GitHub Pages)
├── public/           # Frontend served by the reference API
├── tests/            # GoogleTest suite (-DBUILD_TESTS=ON)
├── Dockerfile        # Multi-stage image
├── render.yaml       # Render deployment config
├── CMakeLists.txt    # FetchContent-ready build
└── .env.example      # Environment variable template

Deployment

Docker

A multi-stage Dockerfile builds the binary and packages a slim runtime image.

docker
docker build -t prism-api .
docker run -p 8080:8080 \
  -e JWT_SECRET_KEY=$(openssl rand -hex 32) \
  -e DATABASE_URL=... prism-api

Render

  • Push the repository to GitHub.
  • Create a new Web Service on Render and connect the repo. render.yaml is detected automatically (Docker runtime, /health health check).
  • Set the two secrets (marked sync: false): JWT_SECRET_KEY and DATABASE_URL.
  • Deploy.

Health check

The /health endpoint reports service and database status, which suits load balancers and uptime monitors.

GET /health
{
  "status": "healthy",
  "version": "0.1.0",
  "environment": "production",
  "database_enabled": true,
  "database_healthy": true
}