Skip to content

Commit

Permalink
refactor: person controller
Browse files Browse the repository at this point in the history
  • Loading branch information
araujo88 committed Apr 9, 2024
1 parent 026545b commit 911a8f4
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 91 deletions.
4 changes: 2 additions & 2 deletions include/person.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
class Person {
public:
std::string name;
int age;
unsigned int age;

Person() = default;
Person(std::string name, int age) : name(name), age(age) {}
Person(std::string name, unsigned int age) : name(name), age(age) {}
};
13 changes: 11 additions & 2 deletions include/person_controller.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "person_serializer.hpp"
#include "person_service.hpp"
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/json.hpp>
Expand All @@ -10,8 +12,15 @@ namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = net::ip::tcp; // from <boost/asio/ip/tcp.hpp>

class PersonController {
private:
std::shared_ptr<IPersonService> personService;

public:
void handleGet(http::response<http::string_body> &response);
void handlePost(const http::request<http::string_body> &request,
PersonController(std::shared_ptr<IPersonService> service)
: personService(service) {}

void getPersons(const http::request<http::string_body> &request,
http::response<http::string_body> &response);
void createPerson(const http::request<http::string_body> &request,
http::response<http::string_body> &response);
};
16 changes: 0 additions & 16 deletions include/person_request_handler.hpp

This file was deleted.

17 changes: 0 additions & 17 deletions include/request_handler.hpp

This file was deleted.

15 changes: 12 additions & 3 deletions include/server.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once

#include "request_handler.hpp"
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <boost/json.hpp>
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <thread>
#include <vector>
Expand All @@ -16,11 +17,19 @@ using tcp = net::ip::tcp; // from <boost/asio/ip/tcp.hpp>

class Server {
private:
std::map<std::string,
std::function<void(const http::request<http::string_body> &,
http::response<http::string_body> &)>>
routeMap;
short port;

public:
Server(short port) : port(port) {}
void session(tcp::socket socket, std::shared_ptr<IRequestHandler> handler);
void run(std::shared_ptr<IRequestHandler> handler);
void addRoute(const std::string &route,
std::function<void(const http::request<http::string_body> &,
http::response<http::string_body> &)>
handler);
void session(tcp::socket socket);
void run();
short getPort();
};
20 changes: 17 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "../include/person_request_handler.hpp"
#include "../include/person_controller.hpp"
#include "../include/person_service.hpp"
#include "../include/server.hpp"
#include <iostream>
Expand All @@ -7,9 +7,23 @@ int main(void) {
try {
auto server = Server(6969);
auto personService = std::make_shared<PersonService>();
auto handler = std::make_shared<PersonRequestHandler>(personService);
auto personController = std::make_shared<PersonController>(personService);

server.addRoute("/person", [personController](
const http::request<http::string_body> &req,
http::response<http::string_body> &res) {
if (req.method() == http::verb::get) {
personController->getPersons(req, res);
} else if (req.method() == http::verb::post) {
personController->createPerson(req, res);
} else {
res.result(http::status::not_found);
res.body() = "Resource not found";
}
});

std::cout << "Server starting on port " << server.getPort() << std::endl;
server.run(handler);
server.run();
} catch (std::exception const &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
Expand Down
36 changes: 36 additions & 0 deletions src/person_controller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "../include/person_controller.hpp"

void PersonController::getPersons(
const http::request<http::string_body> &request,
http::response<http::string_body> &response) {
try {
auto persons = personService->getAllPersons();
boost::json::array jsonArray;
for (const auto &person : persons) {
jsonArray.push_back(PersonSerializer::toJson(person));
}
std::string jsonString = boost::json::serialize(jsonArray);
response.result(http::status::ok);
response.body() = jsonString;
response.set(http::field::content_type, "application/json");
} catch (const std::exception &e) {
response.result(http::status::internal_server_error);
response.body() = "{\"error\": \"Failed to serialize persons.\"}";
response.set(http::field::content_type, "application/json");
}
}

void PersonController::createPerson(
const http::request<http::string_body> &request,
http::response<http::string_body> &response) {
try {
auto json = boost::json::parse(request.body());
auto person = PersonSerializer::fromJson(json.as_object());
personService->addPerson(person);
response.result(http::status::created);
response.body() = "Person created";
} catch (const std::exception &e) {
response.result(http::status::bad_request);
response.body() = "Invalid JSON payload";
}
}
42 changes: 0 additions & 42 deletions src/person_request_handler.cpp

This file was deleted.

28 changes: 22 additions & 6 deletions src/server.cpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
#include "../include/server.hpp"

void Server::session(tcp::socket socket,
std::shared_ptr<IRequestHandler> handler) {
void Server::session(tcp::socket socket) {
try {
beast::flat_buffer buffer;
http::request<http::string_body> request;
http::read(socket, buffer, request);
http::response<http::string_body> response;
handler->handleRequest(request, response);

auto handlerIt = routeMap.find(request.target());
if (handlerIt != routeMap.end()) {
// Call the function handler directly
handlerIt->second(request, response);
} else {
response.result(http::status::not_found);
response.body() = "Route not found";
}

http::write(socket, response);
} catch (std::exception const &e) {
std::cerr << "Error: " << e.what() << std::endl;
std::cerr << "Session error: " << e.what() << std::endl;
}
}

void Server::run(std::shared_ptr<IRequestHandler> handler) {
void Server::run() {
net::io_context io_context{1};
tcp::acceptor acceptor{
io_context, {tcp::v4(), static_cast<boost::asio::ip::port_type>(port)}};
for (;;) {
tcp::socket socket{io_context};
acceptor.accept(socket);
std::thread(&Server::session, this, std::move(socket), handler).detach();
std::thread(&Server::session, this, std::move(socket)).detach();
}
}

void Server::addRoute(
const std::string &route,
std::function<void(const http::request<http::string_body> &,
http::response<http::string_body> &)>
handler) {
routeMap[route] = handler;
}

short Server::getPort() { return port; }

0 comments on commit 911a8f4

Please sign in to comment.