Crest C++ API Documentation
Complete reference for using Crest in C++ projects.
Table of Contents
Getting Started
Include the Crest header in your C++ project:
Use the crest namespace:
App Class
The main application class for creating and managing your API.
Constructor
Example:
// Default constructor
crest::App app;
// With configuration
crest::Config config;
config.title = "My API";
crest::App app(config);
Route Registration Methods
get
Register a GET route.
Parameters:
- path
: Route path
- handler
: Lambda or function to handle requests
- description
: Optional route description
Returns: Reference to App for method chaining
Example:
app.get("/users", [](Request& req, Response& res) {
res.json(Status::OK, R"({"users":[]})");
}, "Get all users");
post
Register a POST route.
Example:
app.post("/users", [](Request& req, Response& res) {
std::string body = req.body();
res.json(Status::CREATED, R"({"message":"Created"})");
}, "Create a user");
put
Register a PUT route.
del
Register a DELETE route.
patch
Register a PATCH route.
route
Register a route with a specific HTTP method.
App& route(Method method, const std::string& path, Handler handler,
const std::string& description = "");
Example:
app.route(Method::GET, "/status", [](Request& req, Response& res) {
res.json(200, R"({"status":"ok"})");
});
Server Control
run
Start the HTTP server.
Parameters:
- host
: Host address (default: "0.0.0.0")
- port
: Port number (default: 8000)
Throws: crest::Exception
on error
Example:
try {
app.run("127.0.0.1", 3000);
} catch (const crest::Exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
stop
Stop the HTTP server.
Configuration Methods
set_title
Set the application title for documentation.
set_description
Set the application description for documentation.
set_docs_enabled
Enable or disable Swagger documentation.
Example:
set_proxy
Configure proxy settings.
Request Class
Represents an HTTP request.
Methods
path
Get the request path.
Returns: Request path
Example:
method
Get the HTTP method.
Returns: HTTP method (e.g., "GET", "POST")
body
Get the request body.
Returns: Request body as string
Example:
query
Get a query parameter value.
Parameters:
- key
: Query parameter key
Returns: Parameter value, or empty string if not found
Example:
header
Get a header value.
Parameters:
- key
: Header key
Returns: Header value, or empty string if not found
Example:
queries
Get all query parameters.
Returns: Map of all query parameters
headers
Get all headers.
Returns: Map of all headers
Response Class
Represents an HTTP response.
Methods
json
Send a JSON response.
Parameters:
- status
: HTTP status code (enum or int)
- json
: JSON string
Example:
text
Send a plain text response.
Example:
html
Send an HTML response.
Example:
set_header
Set a response header.
Example:
Configuration
Config Struct
struct Config {
std::string title = "Crest API";
std::string description = "RESTful API built with Crest";
std::string version = "0.0.0";
bool docs_enabled = true;
std::string docs_path = "/docs";
std::string openapi_path = "/openapi.json";
std::string proxy_url;
int max_connections = 1000;
int timeout_seconds = 30;
};
Example:
crest::Config config;
config.title = "My API";
config.description = "A powerful API";
config.version = "1.0.0";
config.docs_enabled = true;
config.max_connections = 500;
crest::App app(config);
Enums
Method
Status
enum class Status {
OK = 200,
CREATED = 201,
ACCEPTED = 202,
NO_CONTENT = 204,
BAD_REQUEST = 400,
UNAUTHORIZED = 401,
FORBIDDEN = 403,
NOT_FOUND = 404,
METHOD_NOT_ALLOWED = 405,
INTERNAL_ERROR = 500,
NOT_IMPLEMENTED = 501,
SERVICE_UNAVAILABLE = 503
};
Exception Handling
Exception Class
class Exception : public std::exception {
public:
explicit Exception(const std::string& message, int code = 500);
const char* what() const noexcept override;
int code() const noexcept;
};
Example:
try {
app.run("0.0.0.0", 8000);
} catch (const crest::Exception& e) {
std::cerr << "Error " << e.code() << ": " << e.what() << std::endl;
}
Examples
Basic API
#include "crest/crest.hpp"
#include <iostream>
int main() {
crest::App app;
app.get("/", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"message":"Hello, World!"})");
});
app.run("0.0.0.0", 8000);
return 0;
}
RESTful CRUD API
#include "crest/crest.hpp"
int main() {
crest::App app;
// List all
app.get("/users", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"users":[]})");
}, "Get all users");
// Get one
app.get("/users/:id", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"id":1,"name":"John"})");
}, "Get user by ID");
// Create
app.post("/users", [](crest::Request& req, crest::Response& res) {
std::string body = req.body();
res.json(crest::Status::CREATED, R"({"message":"Created"})");
}, "Create a new user");
// Update
app.put("/users/:id", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"message":"Updated"})");
}, "Update user");
// Delete
app.del("/users/:id", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"message":"Deleted"})");
}, "Delete user");
app.run("0.0.0.0", 8000);
return 0;
}
With Configuration
#include "crest/crest.hpp"
int main() {
crest::Config config;
config.title = "My API";
config.description = "A powerful RESTful API";
config.version = "1.0.0";
config.docs_enabled = true;
crest::App app(config);
app.get("/", [](crest::Request& req, crest::Response& res) {
res.json(200, R"({"status":"running"})");
});
try {
app.run("127.0.0.1", 3000);
} catch (const crest::Exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Method Chaining
crest::App app;
app.get("/a", handler1)
.post("/b", handler2)
.put("/c", handler3)
.del("/d", handler4);
app.run();
Best Practices
- Use RAII - App destructor handles cleanup automatically
- Capture by reference in lambdas when needed for performance
- Use Status enum for better code readability
- Handle exceptions around app.run()
- Validate input in your handlers
- Use const references for string parameters
- Disable docs in production for security
Thread Safety
Request handlers are executed in separate threads. Ensure your handlers are thread-safe when accessing shared resources. Use mutexes or other synchronization primitives as needed.
Performance Tips
- Minimize allocations in hot paths
- Use string_view for read-only string operations
- Reserve capacity for containers when size is known
- Avoid unnecessary copies - use move semantics
- Profile your handlers to identify bottlenecks