Ninu nkan yii Emi yoo sọrọ nipa bii MO ṣe ṣẹda awoṣe kan (cookiecutter) ati ṣeto agbegbe kan fun kikọ iṣẹ API REST ni C ++ nipa lilo docker / docker-compose ati oluṣakoso package conan.
Lakoko hackathon t’okan, ninu eyiti Mo kopa bi olupilẹṣẹ ẹhin, ibeere naa dide nipa kini lati lo lati kọ microservice atẹle. Ohun gbogbo ti a ti kọ bẹ jina ti a ti kọ nipa emi ati awọn mi
Nitorinaa, a dojuko pẹlu iṣẹ-ṣiṣe ti kikọ iṣẹ fifuye giga, iṣẹ akọkọ ti eyiti o jẹ lati ṣaju awọn data ti o nbọ si ati kọ si ibi ipamọ data. Ati lẹhin isinmi ẹfin miiran, ọrẹ kan daba pe Emi, gẹgẹbi olupilẹṣẹ C ++, kọ iṣẹ yii ni lilo awọn anfani. Jiyan eyi ni pe yoo yarayara, diẹ sii ni iṣelọpọ, ati ni gbogbogbo, awọn imomopaniyan yoo ni inudidun pẹlu bi a ṣe mọ bi a ṣe le ṣakoso awọn orisun ẹgbẹ. Si eyiti Mo dahun pe Emi ko ṣe iru awọn nkan bẹẹ ni C ++ ati pe MO le ni irọrun ya awọn wakati 20+ to ku si wiwa, ṣajọ ati sisopọ awọn ile-ikawe to dara. Nìkan fi, Mo adie jade. Eyi ni ohun ti a pinnu ati ni idakẹjẹ pari ohun gbogbo ni Python.
Ni bayi, lakoko ipinya ara ẹni ti o fi agbara mu, Mo pinnu lati ro ero bi o ṣe le kọ awọn iṣẹ ni C ++. Ohun akọkọ lati ṣe ni pinnu lori ile-ikawe ti o yẹ. Yiyan mi ṣubu lori
conanfile.txt
[nbeere] poco / 1.9.3
libpq / 11.5
ati pẹlu aṣẹ ti o rọrun "conan fi sori ẹrọ." fi sori ẹrọ awọn pataki ikawe. Nipa ti, o tun jẹ dandan lati ṣe awọn ayipada si
CMakeLists.txt
include(build/conanbuildinfo.cmake)
conan_basic_setup()
target_link_libraries(<target_name> ${CONAN_LIBS})
Lẹ́yìn ìyẹn, mo bẹ̀rẹ̀ sí wá ibi ìkówèésí kan láti máa bá PostgreSQL ṣiṣẹ́, níwọ̀n bí ó ti jẹ́ èyí tí mo ní ìrírí díẹ̀ tí mo bá ń ṣiṣẹ́, ó sì tún jẹ́ èyí tí àwọn iṣẹ́ Python wa bá. Ati pe o mọ ohun ti Mo kọ? O wa ni POCO! Ṣugbọn conan ko mọ pe o wa ni POCO ati pe ko mọ bi o ṣe le kọ; faili iṣeto ti igba atijọ wa ninu ibi ipamọ (Mo ti kọ tẹlẹ nipa aṣiṣe yii si awọn olupilẹṣẹ POCO). Eyi tumọ si pe iwọ yoo ni lati wa ile-ikawe miiran.
Ati lẹhinna yiyan mi ṣubu lori ile-ikawe olokiki ti ko gbajumọ
Igbesẹ ti o tẹle ni lati kọ awoṣe iṣẹ kan ti o le ṣe ilana awọn ibeere.
A gbọdọ jogun kilasi TemplateServerApp wa lati ọdọ Poco :: Util :: ServerApplication ki o si yi ọna akọkọ pada.
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;
}
Ni akọkọ ọna a gbọdọ ṣeto awọn paramita: ibudo, nọmba ti awọn okun ati isinyi iwọn. Ati pataki julọ, o gbọdọ pato olutọju kan fun awọn ibeere ti nwọle. Eyi ni a ṣe nipasẹ ṣiṣẹda ile-iṣẹ kan
TemplateRequestHandlerFactory
class TemplateRequestHandlerFactory : public HTTPRequestHandlerFactory
{
public:
virtual HTTPRequestHandler* createRequestHandler(const HTTPServerRequest & request)
{
return new TemplateServerAppHandler;
}
};
Ninu ọran mi, o rọrun ṣẹda olutọju kanna ni gbogbo igba - TemplateServerAppHandler. Eyi ni ibiti a ti le gbe ọgbọn iṣowo wa.
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();
}
};
Mo tun ṣẹda awoṣe kilasi lati ṣiṣẹ pẹlu PostgreSQL. Lati ṣe SQL ti o rọrun, gẹgẹbi ṣiṣẹda tabili kan, ọna kan wa ExecuteSQL(). Fun awọn ibeere ti o ni eka sii tabi imupadabọ data, iwọ yoo ni lati gba asopọ nipasẹ GetConnection() ati lo API libpg. (Boya nigbamii Emi yoo ṣe atunṣe aiṣododo yii).
database
#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;
};
Gbogbo awọn paramita fun sisopọ si ibi ipamọ data ni a mu lati agbegbe, nitorinaa o tun nilo lati ṣẹda ati tunto faili .env
.env
DATABASE_NAME=template
DATABASE_USER=user
DATABASE_PASSWORD=password
DATABASE_HOST=postgres
DATABASE_PORT=5432
O le wo gbogbo koodu ni
Ati nisisiyi ba wa ni ipele ikẹhin ti kikọ dockerfile ati docker-compose.yml. Lati ṣe otitọ, eyi gba akoko pupọ julọ, kii ṣe nitori pe emi jẹ noob nikan, nitori pe o jẹ dandan lati tun awọn ile-ikawe naa ṣe ni gbogbo igba, ṣugbọn nitori awọn ipalara ti conan. Fun apẹẹrẹ, ni ibere fun conan lati ṣe igbasilẹ, fi sori ẹrọ ati kọ awọn igbẹkẹle pataki, ko to fun lati ṣe igbasilẹ “conan fi sori ẹrọ.”, o tun nilo lati kọja paramita -s compiler.libcxx=libstdc++11, bibẹẹkọ. o ni ewu lati gba opo awọn aṣiṣe ni ipele sisopọ ohun elo rẹ. Mo ti di pẹlu aṣiṣe yii fun awọn wakati pupọ ati pe Mo nireti pe nkan yii yoo ṣe iranlọwọ fun awọn eniyan miiran lati yanju iṣoro yii ni akoko diẹ.
Nigbamii ti, lẹhin kikọ docker-compose.yml, lori imọran ọrẹ mi, Mo ṣafikun atilẹyin
Mo nireti pe awoṣe yii yoo ṣe iranlọwọ fun awọn olubere lori ọna ti o nira wọn ti idagbasoke awọn ohun elo API REST ni nla ati alagbara, ṣugbọn iru ede ti o ni irọra bii C ++.
Paapaa, Mo ṣeduro gíga kika nibi
orisun: www.habr.com