Skip to content

About

No description, website, or topics provided.

Resources

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Repository files navigation

CPP API Framework

Build Status CodeQL License C++

A C++20 framework for building REST APIs with job processing, metrics callbacks, and WebSocket support.

πŸš€ Features

Web Framework

  • REST API Development: Built on top of Pistache HTTP library
  • OpenAPI Documentation: DocAPI helpers record request/response examples and export openapi.json
  • Input Validation: Validators for request fields, types, and formats
  • WebSocket Support: Real-time bidirectional communication
  • HTTP Wrappers: Simplified request/response handling
  • HTTPS Client Utilities: Poco HTTP/HTTPS connection pooling and SSL client initialization

Job Processing System

  • Queueable Jobs: Asynchronous job processing with serialization support
  • Job Execution: Worker loop with optional execution in a forked process
  • Metrics Collection: Job lifecycle callbacks and a console metrics implementation
  • Job Retry Logic: Automatic retry mechanisms for failed jobs
  • Queue Management: Named queues and scheduled jobs with in-memory and Redis backends

Storage & Database

  • MySQL Integration: Native MySQL C++ Connector support
  • Redis Support: Caching and job queues via Poco Redis
  • Storage Controllers: File and data storage abstractions
  • Database Migrations: Schema management utilities

Development Tools

  • Code Generation: Automatic job class generation (newjob.sh)
  • Testing Framework: Google Test integration
  • Code Quality: Clang-tidy and clang-format support

⚠️ Project Status

Important Notice: This is a personal project currently under development and is provided without any warranties or guarantees. The framework is experimental and should not be used in production environments without thorough testing and evaluation. Features may change, and compatibility is not guaranteed across versions.

This project serves primarily as a learning exercise and concept exploration for modern C++20 API development patterns.

πŸ“‹ Requirements

Dependencies

System Requirements

  • Linux (CI runs on ubuntu-latest)
  • Redis Server (for Redis-backed caching, queues, and Redis integration tests)
  • MySQL Server (optional, for database features)

πŸ”§ Installation

Ubuntu/Debian

# Install build tools
sudo apt-get update && sudo apt-get install build-essential cmake ninja-build

# Install Clang (recommended)
sudo apt install clang-18 clang-tidy-18 clang-format

# Install Pistache
sudo add-apt-repository ppa:pistache+team/unstable
sudo apt update && sudo apt install libpistache-dev

# Install other dependencies  
sudo apt-get install libpoco-dev libmysqlcppconn-dev libgtest-dev libssl-dev pkg-config
sudo apt-get install redis-server redis-tools  # Required for Redis integration tests

Build from Source

# Clone the repository
git clone https://github.com/Fabio3rs/cppapiframework.git
cd cppapiframework

# Configure build
mkdir build && cd build
export CC=$(which clang-18)    # Optional: use Clang
export CXX=$(which clang++-18)
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug

# Build
cmake --build . --config Debug --target all -j $(nproc)

# Run tests
ctest -j 20 -C Debug -T test --output-on-failure

🚦 Quick Start

Creating a Simple API

#include "projstdafx.hpp"
#include "WebInterface/WebApp.hpp"

void hello(httpwrappers::Req, httpwrappers::Resp response) {
    response.send(httpwrappers::Code::Ok,
                  R"({"message":"Hello, World!"})",
                  httpwrappers::jsonMimeType());
}

int main() {
    webapp::WebApp app;
    app.init(Pistache::Address("127.0.0.1", 8080), 4);
    app.get("/hello", hello);
    app.start([]() {
        std::cout << "Server running on http://127.0.0.1:8080" << std::endl;
    });
}

For controller-based routing, implement CController::register_routes and attach the controller with CPistacheEndpoint::register_controller.

Creating Background Jobs

#include "projstdafx.hpp"
#include "jobhandler/QueueableJob.hpp"
#include "jobhandler/QueueWorker.hpp"
#include "queues/StdQueue.hpp"

// Define a job class
class EmailJob : public job::QueueableJob {
    std::string recipient;
    std::string subject;
    std::string body;

public:
    QUEUEABLE_SERIALIZE(recipient, subject, body)

    [[nodiscard]] auto getName() const -> std::string override {
        return getTypeNameByInst(*this);
    }

    void handle() override {
        // Send email logic here
        std::cout << "Sending email to: " << recipient << std::endl;
        std::cout << "Subject: " << subject << std::endl;
        
        // Simulate processing time
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    EmailJob() = default;
    EmailJob(std::string to, std::string subj, std::string content)
        : recipient(std::move(to)), subject(std::move(subj)), body(std::move(content)) {}
};

int main() {
    // Create job handler and worker
    auto handler = std::make_shared<job::JobsHandler>();
    handler->register_job_handler<EmailJob>();
    auto queue = std::make_shared<StdQueue>();
    job::QueueWorker worker(handler, queue);
    
    // Queue some jobs
    worker.push("email_queue", EmailJob("user@example.com", "Welcome!", "Welcome to our service"));
    worker.push("email_queue", EmailJob("admin@example.com", "Alert", "System status update"));
    
    // Process jobs
    while (worker.do_one("email_queue")) {}
    
    return 0;
}

Job Metrics Collection

Use the provided console callback with the worker from the previous example, before queuing jobs:

#include "jobhandler/SimpleConsoleMetrics.hpp"

// Inside main(), after constructing worker:
worker.setMetricsCallback(std::make_shared<job::SimpleConsoleMetrics>());

Custom collectors can derive from job::WorkerMetricsCallback. See the callback interface and its tests for the supported events and signatures.

πŸ—οΈ Architecture

Core Components

cppapiframework/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ WebInterface/          # HTTP/REST API components
β”‚   β”‚   β”œβ”€β”€ WebApp.hpp         # Main web application class
β”‚   β”‚   β”œβ”€β”€ CController.hpp    # Base controller class
β”‚   β”‚   └── httpwrappers.hpp   # HTTP utilities
β”‚   β”œβ”€β”€ jobhandler/            # Background job processing
β”‚   β”‚   β”œβ”€β”€ QueueWorker.hpp    # Job worker implementation
β”‚   β”‚   β”œβ”€β”€ QueueableJob.hpp   # Base job class
β”‚   β”‚   └── JobsHandler.hpp    # Job management
β”‚   β”œβ”€β”€ Database/              # Database integration
β”‚   β”œβ”€β”€ Storage/               # File storage utilities
β”‚   β”œβ”€β”€ WebSocket/             # WebSocket support
β”‚   β”œβ”€β”€ utils/                 # Utility classes
β”‚   β”‚   └── DocAPI.hpp         # OpenAPI documentation
β”‚   └── boot.hpp               # Application bootstrap
β”œβ”€β”€ tests/                     # Unit tests
└── example_metrics_usage.cpp  # Usage examples

Design Patterns

  • Controllers: CController subclasses register HTTP routes with CPistacheEndpoint
  • Observer Pattern: Metrics collection via callbacks
  • Template Metaprogramming: Job serialization system
  • RAII: Resource management throughout
  • Factory Pattern: Job creation and handling

πŸ§ͺ Testing

Run the test suite:

cd build
ctest -j 20 -C Debug -T test --output-on-failure

Individual test categories:

# Run specific tests
./bin/apiframework_test --gtest_filter='InputValidatorTest.*'
./bin/apiframework_test --gtest_filter='TestWorkerMetrics.*'

πŸ“š Documentation

  • Metrics System: Comprehensive guide to job metrics collection
  • Implementation Summary: Recent feature implementations
  • API Documentation: DocAPI recording macros are enabled when NDEBUG is not defined; call DocAPI::singleton().dump() to write openapi.json

πŸ› οΈ Development

Code Generation

Generate new job classes:

mkdir -p src/jobs
./newjob.sh MyNewJob

Code Style

The project uses enhanced security-focused static analysis tools:

# Format code
clang-format -i src/**/*.cpp src/**/*.hpp

# Run enhanced security-focused static analysis
clang-tidy src/**/*.cpp --checks='-*,cert-*,bugprone-*,clang-analyzer-security*,cppcoreguidelines-*' -- -std=c++20

# Run additional security analysis
cppcheck --enable=all --std=c++20 src/

πŸ›‘οΈ Security

The repository includes static analysis configuration and CI workflows for security checks:

Security Scanning Tools

  • CodeQL: GitHub's semantic code analysis engine
  • Enhanced clang-tidy: Security-focused static analysis with cert-, bugprone-, and security rules
  • cppcheck: Additional static analysis for memory safety and undefined behavior
  • Dependabot: Weekly update checks for GitHub Actions dependencies
  • SBOM Generation: The security workflow invokes Syft to generate an SBOM and Grype to scan it

Validation and Database Helpers

  • Input Validation: Field validators in InputValidators and request validation through WebInputValidator
  • SQL Helpers: MySQL string escaping in CSql and prepared statements in migration lookup

Security Policy

For security vulnerabilities, please refer to our Security Policy. DO NOT create public issues for security vulnerabilities.

Security Build Features

The CI workflows pass additional compiler and linker hardening flags explicitly. To use similar flags locally:

# Security-hardened build
cmake .. -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CXX_FLAGS="-Wall -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=3 -fPIE" \
  -DCMAKE_EXE_LINKER_FLAGS="-pie -Wl,-z,relro,-z,now"

Building with Different Compilers

# GCC
export CC=gcc CXX=g++

# Clang (recommended)
export CC=clang-18 CXX=clang++-18

cmake .. -G Ninja

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes following the existing code style
  4. Add tests for new functionality
  5. Ensure all tests pass: ctest
  6. Commit your changes: git commit -m 'Add amazing feature'
  7. Push to the branch: git push origin feature/amazing-feature
  8. Open a Pull Request

Code Style Guidelines

  • Use C++20 features when appropriate
  • Follow RAII principles
  • Add comprehensive tests for new features
  • Document public APIs with Doxygen comments
  • Use clang-format for consistent formatting

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support


Note: This framework is actively developed and some features may be experimental. Please check the issues and documentation for the latest information.

About

No description, website, or topics provided.

Resources

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages