In questu articulu, parleraghju di cumu aghju creatu un mudellu (cookiecutter) è stabilisce un ambiente per scrive un serviziu API REST in C++ usendu docker/docker-compose è u gestore di pacchetti conan.
Duranti u prossimu hackathon, in quale aghju participatu cum'è sviluppatore di backend, a quistione hè stata di ciò chì aduprà per scrive u prossimu microserviziu. Tuttu ciò chì hè statu scrittu finu à avà hè statu scrittu da mè è u mo
Cusì, avemu statu affruntatu cù u compitu di scrive un serviziu high-load, u compitu principale di quale era di preprocessà i dati chì venenu à ellu è scrive in a basa di dati. È dopu à un'altra pausa di fumu, un amicu suggerì chì, cum'è sviluppatore C++, scrive stu serviziu cù i prufessiunali. Argumentendu questu hè chì serà più veloce, più pruduttivu, è in generale, u ghjuridiu serà piacè di cumu sapemu cumu gestisce e risorse di a squadra. À quale aghju rispostu chì ùn aghju mai fattu tali cose in C ++ è puderia facilmente dedicà l'ora di 20+ restante à a ricerca, a compilazione è a ligame di biblioteche adattate. Simply put, I chicken out. Hè ciò chì avemu decisu è cumpletamu tranquillamente tuttu in Python.
Avà, durante l'autoisolamentu furzatu, decisu di capisce cumu scrive servizii in C++. A prima cosa da fà era decide di una biblioteca adattata. A mo scelta hè cascata
conanfile.txt
[necessita] poco/1.9.3
libpq/11.5
è cù un cumandimu simplice "conan install". installà e librerie necessarie. Naturalmente, era ancu necessariu di fà cambiamenti
CMakeLists.txt
include(build/conanbuildinfo.cmake)
conan_basic_setup()
target_link_libraries(<target_name> ${CONAN_LIBS})
Dopu quì, aghju cuminciatu à circà una biblioteca per travaglià cù PostgreSQL, postu chì era quellu chì aghju avutu pocu sperienza di travaglià, è era ancu quellu chì i nostri servizii Python interagiscenu cù. E sapete ciò chì aghju amparatu ? Hè in POCO! Ma Conan ùn sapi micca chì hè in POCO è ùn sapi micca cumu custruisce; ci hè un schedariu di cunfigurazione anticu in u repository (aghju digià scrittu annantu à questu errore à i creatori di POCO). Questu significa chì avete da circà una altra biblioteca.
È tandu a mo scelta hè cascata nantu à una biblioteca menu pupulare
U passu prossimu era di scrive un mudellu di serviziu chì pò processà e dumande.
Avemu da eredite a nostra classe TemplateServerApp da Poco::Util::ServerApplication è annullà u metudu principale.
TemplateServerApp
#pragma once
#include <string>
#include <vector>
#include <Poco/Util/ServerApplication.h>
class TemplateServerApp : public Poco::Util::ServerApplication
{
protected:
int main(const std::vector<std::string> &);
};
int TemplateServerApp::main(const vector<string> &)
{
HTTPServerParams* pParams = new HTTPServerParams;
pParams->setMaxQueued(100);
pParams->setMaxThreads(16);
HTTPServer s(new TemplateRequestHandlerFactory, ServerSocket(8000), pParams);
s.start();
cerr << "Server started" << endl;
waitForTerminationRequest(); // wait for CTRL-C or kill
cerr << "Shutting down..." << endl;
s.stop();
return Application::EXIT_OK;
}
In u metudu principale, avemu da stabilisce i paràmetri: u portu, u numeru di fili è a dimensione di a fila. È più impurtante, duvete specificà un gestore per e richieste entrate. Questu hè fattu da a creazione di una fabbrica
TemplateRequestHandlerFactory
class TemplateRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest & request)
{
return new TemplateServerAppHandler;
}
};
In u mo casu, simpricimenti crea u listessu gestore ogni volta - TemplateServerAppHandler. Questu hè induve pudemu mette a nostra logica cummerciale.
TemplateServerAppHandler
class TemplateServerAppHandler : public HTTPRequestHandler
{
public:
void handleRequest(HTTPServerRequest &req, HTTPServerResponse &resp)
{
URI uri(req.getURI());
string method = req.getMethod();
cerr << "URI: " << uri.toString() << endl;
cerr << "Method: " << req.getMethod() << endl;
StringTokenizer tokenizer(uri.getPath(), "/", StringTokenizer::TOK_TRIM);
HTMLForm form(req,req.stream());
if(!method.compare("POST"))
{
cerr << "POST" << endl;
}
else if(!method.compare("PUT"))
{
cerr << "PUT" << endl;
}
else if(!method.compare("DELETE"))
{
cerr << "DELETE" << endl;
}
resp.setStatus(HTTPResponse::HTTP_OK);
resp.setContentType("application/json");
ostream& out = resp.send();
out << "{"hello":"heh"}" << endl;
out.flush();
}
};
Aghju ancu creatu un mudellu di classi per travaglià cù PostgreSQL. Per fà SQL simplice, cum'è a creazione di una tavola, ci hè un metudu ExecuteSQL (). Per dumande più cumplesse o ricuperazione di dati, avete da ottene una cunnessione via GetConnection () è utilizate l'API libpg. (Forse dopu correraghju sta inghjustizia).
Archivio
#pragma once
#include <memory>
#include <mutex>
#include <libpq-fe.h>
class Database
{
public:
Database();
std::shared_ptr<PGconn> GetConnection() const;
bool ExecuteSQL(const std::string& sql);
private:
void establish_connection();
void LoadEnvVariables();
std::string m_dbhost;
int m_dbport;
std::string m_dbname;
std::string m_dbuser;
std::string m_dbpass;
std::shared_ptr<PGconn> m_connection;
};
Tutti i paràmetri per cunnette à a basa di dati sò pigliati da l'ambienti, cusì avete bisognu di creà è cunfigurà u schedariu .env.
.env
DATABASE_NAME=template
DATABASE_USER=user
DATABASE_PASSWORD=password
DATABASE_HOST=postgres
DATABASE_PORT=5432
Pudete vede tuttu u codice à
È avà vene l'ultima tappa di scrive u dockerfile è docker-compose.yml. Per esse onestu, questu hà pigliatu a maiò parte di u tempu, è micca solu perchè sò un noob, perchè era necessariu di ricustruisce e biblioteche ogni volta, ma per via di i picciotti di conan. Per esempiu, per cunan per scaricà, installà è custruisce e dipendenze necessarie, ùn hè micca abbastanza per scaricà "conan install .", hè ancu bisognu di passà u paràmetru -s compiler.libcxx=libstdc++ 11, altrimenti. rischiate di ottene una mansa di errori in u stadiu di ligame di a vostra applicazione. Sò statu chjappu cù questu errore per parechje ore è speru chì questu articulu aiuterà altre persone à risolve stu prublema in menu tempu.
Dopu, dopu avè scrittu docker-compose.yml, nantu à i cunsiglii di u mo amicu, aghju aghjustatu supportu
Spergu chì stu mudellu aiuterà i principianti nantu à a so strada difficiule di sviluppà l'applicazioni REST API in u grande è putente, ma una lingua cusì goffa cum'è C ++.
Inoltre, vi cunsigliu assai di leghje quì
Source: www.habr.com