164 lines
3.7 KiB
Markdown
164 lines
3.7 KiB
Markdown
# Goldfish HTTP Router
|
|
A fast radix tree-based HTTP router for C++.
|
|
|
|
## Quick Start
|
|
|
|
```cpp
|
|
#include "goldfish.hpp"
|
|
using namespace goldfish;
|
|
|
|
Router router;
|
|
|
|
// Basic route
|
|
router.get("/hello", [](IRequest& req, IResponse& res, Params params) {
|
|
res.set_body("Hello, World!");
|
|
});
|
|
|
|
// Route with parameters
|
|
router.get("/users/:id", [](IRequest& req, IResponse& res, Params params) {
|
|
string user_id = string(params[0]);
|
|
res.set_body("User ID: " + user_id);
|
|
});
|
|
|
|
// Multiple parameters
|
|
router.get("/users/:userId/posts/:postId", [](IRequest& req, IResponse& res, Params params) {
|
|
string user_id = string(params[0]);
|
|
string post_id = string(params[1]);
|
|
res.set_json("{\"user\":\"" + user_id + "\",\"post\":\"" + post_id + "\"}");
|
|
});
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Router Methods
|
|
|
|
```cpp
|
|
void get(string_view path, Handler handler);
|
|
void post(string_view path, Handler handler);
|
|
void put(string_view path, Handler handler);
|
|
void del(string_view path, Handler handler); // DELETE
|
|
void patch(string_view path, Handler handler);
|
|
|
|
bool handle(IRequest& request, IResponse& response);
|
|
```
|
|
|
|
### Handler Signature
|
|
|
|
```cpp
|
|
using Params = const std::vector<string_view>&;
|
|
using Handler = std::function<void(IRequest&, IResponse&, Params)>;
|
|
```
|
|
|
|
### Path Parameters
|
|
|
|
Use `:name` syntax for parameters:
|
|
- `/users/:id` matches `/users/123`
|
|
- `/api/:version/users/:id` matches `/api/v1/users/456`
|
|
|
|
Parameters are accessed by index in order of appearance:
|
|
```cpp
|
|
router.get("/api/:version/users/:id", [](IRequest& req, IResponse& res, Params params) {
|
|
string version = string(params[0]); // :version
|
|
string id = string(params[1]); // :id
|
|
});
|
|
```
|
|
|
|
## HTTP Server Example
|
|
|
|
```cpp
|
|
#include "goldfish.hpp"
|
|
#include <iostream>
|
|
#include <thread>
|
|
// Your HTTP server headers here
|
|
|
|
using namespace goldfish;
|
|
|
|
class MyRequest : public IRequest {
|
|
private:
|
|
HttpMethod method_;
|
|
string_view path_;
|
|
// ... other fields
|
|
|
|
public:
|
|
MyRequest(const ServerRequest& req) {
|
|
// Parse from your server's request format
|
|
method_ = parse_method(req.method);
|
|
path_ = req.path;
|
|
}
|
|
|
|
HttpMethod method() const override { return method_; }
|
|
string_view path() const override { return path_; }
|
|
// ... implement other methods
|
|
};
|
|
|
|
class MyResponse : public IResponse {
|
|
private:
|
|
ServerResponse& response_;
|
|
|
|
public:
|
|
MyResponse(ServerResponse& res) : response_(res) {}
|
|
|
|
void set_status(int status) override {
|
|
response_.status = status;
|
|
}
|
|
|
|
void set_body(string_view body) override {
|
|
response_.body = string(body);
|
|
}
|
|
// ... implement other methods
|
|
};
|
|
|
|
int main() {
|
|
Router router;
|
|
|
|
// Define routes
|
|
router.get("/", [](IRequest& req, IResponse& res, Params params) {
|
|
res.set_content_type("text/html");
|
|
res.set_body("<h1>Welcome to Goldfish!</h1>");
|
|
});
|
|
|
|
router.get("/api/users/:id", [](IRequest& req, IResponse& res, Params params) {
|
|
string user_id = string(params[0]);
|
|
res.set_content_type("application/json");
|
|
res.set_body("{\"id\":\"" + user_id + "\",\"name\":\"User " + user_id + "\"}");
|
|
});
|
|
|
|
router.post("/api/users", [](IRequest& req, IResponse& res, Params params) {
|
|
// Create user logic
|
|
res.set_status(201);
|
|
res.set_body("{\"message\":\"User created\"}");
|
|
});
|
|
|
|
// Start server
|
|
HttpServer server;
|
|
server.on_request([&](ServerRequest& req, ServerResponse& res) {
|
|
MyRequest request(req);
|
|
MyResponse response(res);
|
|
|
|
if (!router.handle(request, response)) {
|
|
response.set_status(404);
|
|
response.set_body("Not Found");
|
|
}
|
|
});
|
|
|
|
server.listen(8080);
|
|
std::cout << "Server running on port 8080\n";
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
## Performance
|
|
|
|
Benchmarked on typical hardware:
|
|
- **Lookup speed**: 364K lookups/second
|
|
- **Average latency**: 2.75μs per lookup
|
|
- **Memory**: Zero allocations during routing
|
|
- **Scalability**: Linear with route count
|
|
|
|
## Building
|
|
|
|
```bash
|
|
g++ -std=c++20 -O3 your_app.cpp -o your_app
|
|
```
|