Å ajÄ rakstÄ es runÄÅ”u par to, kÄ es izveidoju veidni (cookiecutter) un izveidoju vidi REST API pakalpojuma rakstÄ«Å”anai programmÄ C++, izmantojot docker/docker-compose un conan pakotÅu pÄrvaldnieku.
NÄkamajÄ hakatonÄ, kurÄ piedalÄ«jos kÄ aizmugursistÄmas izstrÄdÄtÄjs, radÄs jautÄjums par to, ar ko rakstÄ«t nÄkamo mikroservisu. Viss, kas lÄ«dz Å”im ir rakstÄ«ts, esmu rakstÄ«ts es un mani
TÄtad, mÄs saskÄrÄmies ar uzdevumu uzrakstÄ«t augstas slodzes pakalpojumu, kura galvenais uzdevums bija iepriekÅ” apstrÄdÄt tajÄ ienÄkoÅ”os datus un ierakstÄ«t tos datu bÄzÄ. Un pÄc kÄrtÄjÄs dÅ«mu pauzes draugs ieteica man kÄ C++ izstrÄdÄtÄjam uzrakstÄ«t Å”o pakalpojumu, izmantojot profesionÄļus. Tas ir arguments, ka tas bÅ«s ÄtrÄk, produktÄ«vÄk, un kopumÄ Å¾Å«rija bÅ«s sajÅ«smÄ par to, kÄ mÄs zinÄm, kÄ pÄrvaldÄ«t komandas resursus. Uz ko es atbildÄju, ka nekad neesmu darÄ«jis tÄdas lietas C++ valodÄ un atlikuÅ”Äs 20+ stundas varÄtu viegli veltÄ«t piemÄrotu bibliotÄku meklÄÅ”anai, apkopoÅ”anai un saistÄ«Å”anai. VienkÄrÅ”Äk sakot, es sastingu. TÄ mÄs nolÄmÄm un mierÄ«gi visu pabeidzÄm Python.
Tagad, piespiedu paÅ”izolÄcijas laikÄ, es nolÄmu izdomÄt, kÄ rakstÄ«t pakalpojumus C++ valodÄ. Vispirms bija jÄizlemj par piemÄrotu bibliotÄku. Mana izvÄle krita
conanfile.txt
[nepiecieŔams]poco/1.9.3
libpq/11.5
un ar vienkÄrÅ”u komandu "conan install." instalÄjiet nepiecieÅ”amÄs bibliotÄkas. Protams, bija arÄ« jÄveic izmaiÅas
CMakeLists.txt
include(build/conanbuildinfo.cmake)
conan_basic_setup()
target_link_libraries(<target_name> ${CONAN_LIBS})
PÄc tam es sÄku meklÄt bibliotÄku darbam ar PostgreSQL, jo ar to man bija maz pieredzes, un ar to arÄ« mijiedarbojÄs mÅ«su Python pakalpojumi. Un vai jÅ«s zinÄt, ko es uzzinÄju? Tas ir POCO! Bet Conan nezina, ka tas atrodas POCO, un nezina, kÄ to izveidot; repozitorijÄ ir novecojis konfigurÄcijas fails (es jau rakstÄ«ju par Å”o kļūdu POCO veidotÄjiem). Tas nozÄ«mÄ, ka jums bÅ«s jÄmeklÄ cita bibliotÄka.
Un tad mana izvÄle krita uz kÄdu mazÄk populÄru bibliotÄku
NÄkamais solis bija uzrakstÄ«t pakalpojuma veidni, kas var apstrÄdÄt pieprasÄ«jumus.
Mums ir jÄmanto sava TemplateServerApp klase no Poco::Util::ServerApplication un jÄignorÄ galvenÄ metode.
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;
}
GalvenajÄ metodÄ mums jÄiestata parametri: ports, pavedienu skaits un rindas lielums. Un pats galvenais, jums ir jÄnorÄda ienÄkoÅ”o pieprasÄ«jumu apstrÄdÄtÄjs. Tas tiek darÄ«ts, izveidojot rÅ«pnÄ«cu
TemplateRequestHandlerFactory
class TemplateRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest & request)
{
return new TemplateServerAppHandler;
}
};
ManÄ gadÄ«jumÄ tas vienkÄrÅ”i katru reizi izveido vienu un to paÅ”u apdarinÄtÄju - TemplateServerAppHandler. Å eit mÄs varam izvietot savu biznesa loÄ£iku.
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();
}
};
Es arÄ« izveidoju klases veidni darbam ar PostgreSQL. Lai veiktu vienkÄrÅ”u SQL, piemÄram, izveidotu tabulu, ir metode ExecuteSQL(). SarežģītÄkiem vaicÄjumiem vai datu izguvei jums bÅ«s jÄiegÅ«st savienojums, izmantojot GetConnection() un izmantojiet libpg API. (VarbÅ«t vÄlÄk Å”o netaisnÄ«bu izlaboÅ”u).
DatubÄze
#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;
};
Visi parametri savienojumam ar datu bÄzi tiek Åemti no vides, tÄpÄc jÄizveido un jÄkonfigurÄ arÄ« .env fails
.env
DATABASE_NAME=template
DATABASE_USER=user
DATABASE_PASSWORD=password
DATABASE_HOST=postgres
DATABASE_PORT=5432
Visu kodu varat redzÄt vietnÄ
Un tagad ir pÄdÄjais dokumenta dockerfile un docker-compose.yml rakstÄ«Å”anas posms. GodÄ«gi sakot, tas aizÅÄma lielÄko daļu laika, un ne tikai tÄpÄc, ka esmu necilvÄks, jo katru reizi bija nepiecieÅ”ams atjaunot bibliotÄkas, bet arÄ« konana kļūmju dÄļ. PiemÄram, lai conan lejupielÄdÄtu, instalÄtu un izveidotu nepiecieÅ”amÄs atkarÄ«bas, nepietiek tikai ar āconan install .ā lejupielÄdi, tam ir arÄ« jÄnodod parametrs -s compiler.libcxx=libstdc++11, pretÄjÄ gadÄ«jumÄ. jÅ«s riskÄjat iegÅ«t virkni kļūdu lietojumprogrammas saistÄ«Å”anas posmÄ. Es esmu iestrÄdzis ar Å”o kļūdu vairÄkas stundas, un es ceru, ka Å”is raksts palÄ«dzÄs citiem cilvÄkiem atrisinÄt Å”o problÄmu Ä«sÄkÄ laikÄ.
PÄc tam, kad es uzrakstÄ«ju docker-compose.yml, pÄc sava drauga ieteikuma pievienoju atbalstu
Es ceru, ka Ŕī veidne palÄ«dzÄs iesÄcÄjiem grÅ«tajÄ ceļÄ, izstrÄdÄjot REST API lietojumprogrammas lieliskajÄ un jaudÄ«gajÄ, taÄu tik neveiklÄ valodÄ kÄ C++.
TurklÄt es ļoti iesaku lasÄ«t Å”eit
Avots: www.habr.com