Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build_utils_module
2 changes: 0 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@


# Clang-tidy configuration
build:clang-tidy --aspects @bazel_clang_tidy//clang_tidy:clang_tidy.bzl%clang_tidy_aspect
build:clang-tidy --output_groups=report
Expand All @@ -21,4 +20,3 @@ build:clang-format --config=clang-format-base \
build:clang-format-fix --config=clang-format-base \
--aspects=@bazel_clang_format//:defs.bzl%fix_aspect \
--use_action_cache=false

30 changes: 18 additions & 12 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@ bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.16")
bazel_dep(name = "cpp-httplib", version = "0.22.0")
bazel_dep(name = "nlohmann_json", version = "3.12.0.bcr.1")


bazel_dep(name = "googletest", version = "1.17.0", dev_dependency = True)
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True)
bazel_dep(name = "bazel_clang_format", version = "0.0.1", dev_dependency = True)
bazel_dep(name = "bazel_clang_tidy", version = "0.0.1", dev_dependency = True)

# Build Utils
bazel_dep(name = "build_utils", version = "0.0.1")
local_path_override(
module_name = "build_utils",
path = "build_utils_module",
)

# LLVM Setup
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)
llvm.toolchain(
llvm_version = "21.1.6",
)
use_repo(llvm, "llvm_toolchain")
register_toolchains("@llvm_toolchain//:all", dev_dependency = True)


# Overrides for dependencies used by build_utils (root module must define these if not in registry)
git_override(
module_name = "bazel_clang_format",
remote = "https://github.com/oliverlee/bazel_clang_format.git",
Expand All @@ -26,16 +42,6 @@ git_override(
commit = "9e54bbb15d1939a9d030c52f3032886a0b278f98",
)

# LLVM Setup
Comment thread
Yuki-cpp marked this conversation as resolved.
llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)
llvm.toolchain(
llvm_version = "21.1.6",
)
use_repo(llvm, "llvm_toolchain")
register_toolchains("@llvm_toolchain//:all", dev_dependency = True)


bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
git_override(
module_name = "hedron_compile_commands",
remote = "https://github.com/mikael-s-persson/bazel-compile-commands-extractor.git",
Expand Down
97 changes: 43 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,95 +1,84 @@
# rest-api-helper
# Rest API Helper

A simple helper library for C++ aimed at making the creation of REST APIs easier and cleaner. It is built on top of [cpp-httplib](https://github.com/yhirose/cpp-httplib) and [nlohmann/json](https://github.com/nlohmann/json).
A C++ library to simplify the creation of REST APIs using `cpp-httplib`, featuring automatic documentation generation.

## Features

- **Route Management**: Define routes and endpoints with a fluent API.
- **Auto-Documentation**: Automatically generates a JSON documentation endpoint for your API.
- **Parameter Descriptions**: Add descriptions for path parameters and request/response details.
- **Bazel Support**: Ready to be integrated into Bazel projects.
- **Route Management**: Organize routes and endpoints hierarchically.
- **Auto-Documentation**: Automatically generates a JSON schema of your API endpoints.
- **Easy Integration**: Wraps `httplib::Server` for seamless integration.

## Installation

This library is designed to be used with Bazel with Bzlmod enabled.
This project uses Bazel for building and dependency management.

### 1. Add dependency to `MODULE.bazel`
### Dependency

Add the following to your `MODULE.bazel`:
Add `rest_api_helper` to your `MODULE.bazel`. If you are using it locally:

```python
# Assuming you have this in a registry or local override
```starlark
bazel_dep(name = "rest_api_helper", version = "0.0.1")
```

### 2. Add dependency to your `BUILD` file

In your `BUILD` or `BUILD.bazel` file, add the library to your target's `deps`:

```python
cc_binary(
name = "my_app",
srcs = ["main.cpp"],
deps = [
"@rest_api_helper//src:rest_api_helper",
],
local_path_override(
module_name = "rest_api_helper",
path = "path/to/rest_api_helper",
)
```

## Usage

Here is a simple example of how to use the library:

```cpp
#include <httplib.h>
#include "src/rest_api.hpp"
#include <httplib.h>

int main()
{
httplib::Server server;
// Initialize the API helper with a base route "/api"
yuki::web::RestAPI api(server, "/api");
int main() {
httplib::Server svr;
yuki::web::RestAPI api(svr, "/api/v1");

// Enable the documentation endpoint at "/api/docs"
api.add_docs_endpoint("docs");
// Add a route
auto& users_route = api.add_route("users", "Operations on users");

// Add a route "/api/hello"
auto& hello_route = api.add_route("hello", "A simple hello route");

// Add a GET endpoint to the route
hello_route.add_endpoint(
// Add an endpoint to the route
users_route.add_endpoint(
yuki::web::HTTPMethod::HTTP_GET,
[](const httplib::Request&, httplib::Response& res) {
res.set_content("Hello, World!", "text/plain");
[](const httplib::Request& req, httplib::Response& res) {
res.set_content("List of users", "text/plain");
},
"Returns a hello message"
"Get all users"
);

// Start the server
server.listen("0.0.0.0", 8080);
// Add documentation endpoint
api.add_docs_endpoint("docs");

svr.listen("0.0.0.0", 8080);
return 0;
}
```

See `examples/basic_usage.cpp` for a more complete example.
## Build System

This project is built with Bazel and relies on a separate `build_utils` module for toolchain configuration and strict compilation flags.

### Modules

## Building and Testing
- **rest_api_helper**: The main library.
- **build_utils**: Provides toolchains (LLVM) and strict build macros.

To build the library:
### Building

```bash
bazel build //src:rest_api_helper
bazel build //...
```

To run the tests:
### Testing

```bash
bazel test //tests:unit_tests
bazel test //...
```

## Dependencies
### Formatting

- [cpp-httplib](https://github.com/yhirose/cpp-httplib)
- [nlohmann/json](https://github.com/nlohmann/json)
- [googletest](https://github.com/google/googletest) (for testing)
To automatically format the code using the project's configuration:

```bash
bazel build //... --config=clang-format-fix
```
1 change: 1 addition & 0 deletions build_utils/BUILD.bazel → build_utils_module/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package(default_visibility = ["//visibility:public"])

# Export defs.bzl so it can be loaded by other modules
exports_files(["defs.bzl"])
9 changes: 9 additions & 0 deletions build_utils_module/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module(
name = "build_utils",
version = "0.0.1",
)

bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_cc", version = "0.2.16")
bazel_dep(name = "bazel_clang_format", version = "0.0.1")
bazel_dep(name = "bazel_clang_tidy", version = "0.0.1")
80 changes: 80 additions & 0 deletions build_utils_module/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Build Utils Module

This module provides common build utilities and macros for strict C++ development using Bazel.

## Features

- **Strict C++ Macros**: Wrappers around `cc_library`, `cc_binary`, and `cc_test` that enforce C++20 and warnings-as-errors.
- **Dependencies**: It declares dependencies on `bazel_clang_format` and `bazel_clang_tidy`, simplifying version management (though root module overrides may still be needed).

## Usage

### 1. Add dependency in `MODULE.bazel`

```starlark
bazel_dep(name = "build_utils", version = "0.0.1")
```

If you are using it locally:

```starlark
local_path_override(
module_name = "build_utils",
path = "path/to/build_utils",
)
```

### 2. Configure Toolchains (Required in Root Module)

Due to Bazel restrictions (`toolchains_llvm` must be used by the root module), you must configure the toolchain in your project's `MODULE.bazel`:

```starlark
bazel_dep(name = "toolchains_llvm", version = "1.6.0", dev_dependency = True)

llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)
llvm.toolchain(
llvm_version = "21.1.6",
)
use_repo(llvm, "llvm_toolchain")
register_toolchains("@llvm_toolchain//:all", dev_dependency = True)
```

### 3. Configure `.bazelrc`

To use `clang-format` and `clang-tidy` with the LLVM toolchain:

```bash
# Clang-tidy configuration
build:clang-tidy --aspects @bazel_clang_tidy//clang_tidy:clang_tidy.bzl%clang_tidy_aspect
build:clang-tidy --output_groups=report
build:clang-tidy --@bazel_clang_tidy//:clang_tidy_config=//:clang_tidy_config
build:clang-tidy --@bazel_clang_tidy//:clang_tidy_executable=@llvm_toolchain//:clang-tidy

# Clang-format configuration
build:clang-format-base --output_groups=report
build:clang-format-base --@bazel_clang_format//:config=//:clang-format-config
build:clang-format-base --@bazel_clang_format//:binary=@llvm_toolchain//:clang-format

# Check-only mode
build:clang-format --config=clang-format-base \
--aspects=@bazel_clang_format//:defs.bzl%check_aspect

# Fix mode
build:clang-format-fix --config=clang-format-base \
--aspects=@bazel_clang_format//:defs.bzl%fix_aspect \
--use_action_cache=false
```

### 4. Use Strict Macros

In your `BUILD.bazel` files:

```starlark
load("@build_utils//:defs.bzl", "strict_cc_library", "strict_cc_binary", "strict_cc_test")

strict_cc_library(
name = "my_lib",
srcs = ["my_lib.cpp"],
hdrs = ["my_lib.hpp"],
)
```
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//build_utils:defs.bzl", "strict_cc_binary")
load("@build_utils//:defs.bzl", "strict_cc_binary")

strict_cc_binary(
name = "basic_usage",
Expand Down
2 changes: 1 addition & 1 deletion src/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//build_utils:defs.bzl", "strict_cc_library")
load("@build_utils//:defs.bzl", "strict_cc_library")

strict_cc_library(
name = "rest_api_helper",
Expand Down
2 changes: 1 addition & 1 deletion tests/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//build_utils:defs.bzl", "strict_cc_test")
load("@build_utils//:defs.bzl", "strict_cc_test")

strict_cc_test(
name = "unit_tests",
Expand Down