{"id":30782,"date":"2019-10-31T21:37:25","date_gmt":"2019-10-31T18:37:25","guid":{"rendered":"https:\/\/prohoster.info\/blog\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu\/"},"modified":"2019-10-31T21:37:25","modified_gmt":"2019-10-31T18:37:25","slug":"razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","title":{"rendered":"Dezvoltarea serverelor web pe Golang \u2014 de la simplu la complex","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Dezvoltarea serverelor web pe Golang \u2014 de la simplu la complex\" src=\"\/wp-content\/uploads\/2019\/04\/4ee879ad45f0ed192a15705e20ae00dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAcum cinci ani, am \u00eenceput <noindex><a rel=\"nofollow\" href=\"https:\/\/getgophish.com\/\">s\u0103 dezvolt Gophish<\/a><\/noindex>, ceea ce mi-a permis s\u0103 \u00eenv\u0103\u021b Golang. Am realizat c\u0103 Go este un limbaj puternic, al c\u0103rui poten\u021bial este completat de numeroase biblioteci. Go este versatil: \u00een special, cu ajutorul s\u0103u, este u\u0219or s\u0103 dezvol\u021bi aplica\u021bii server.<\/p>\n<p>Acest articol este dedicat scrierii unui server \u00een Go. Vom \u00eencepe cu lucruri simple, cum ar fi \u201eHello world!\u201d, \u0219i vom termina cu o aplica\u021bie cu urm\u0103toarele func\u021bionalit\u0103\u021bi:<\/p>\n<p>\u2014 Utilizarea Let\u2019s Encrypt pentru HTTPS.<br \/>\n\u2014 Func\u021bionarea ca API router.<br \/>\n\u2014 Lucrul cu middleware.<br \/>\n\u2014 Gestionarea fi\u0219ierelor statice.<br \/>\n\u2014 \u00cencheiere corect\u0103.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Skillbox recomand\u0103:<\/b> Curs practic <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/python\/?utm_source=skillbox.media&amp;utm_medium=habr.com&amp;utm_campaign=PTNDEV&amp;utm_content=articles&amp;utm_term=gowebserver\">\u201eDezvoltator Python de la zero\u201d<\/a><\/noindex>.<\/p>\n<p><b>V\u0103 reamintim:<\/b> <i>pentru to\u021bi cititorii \u201eHabr\u201d \u2014 reducere de 10.000 de ruble la \u00eenscrierea la orice curs Skillbox cu codul de promovare \u201eHabr\u201d.<\/i>\n<\/p><\/blockquote>\n<h3>Hello, world!<\/h3>\n<p>\nCrearea unui server web \u00een Go se poate face foarte repede. Iat\u0103 un exemplu de utilizare a unui handler care returneaz\u0103 celebrul \u201eHello, world!\u201d.<\/p>\n<pre><code class=\"go\">package main\n \nimport (\n\"fmt\"\n\"net\/http\"\n)\n \nfunc main() {\nhttp.HandleFunc(\"\/\", func(w http.ResponseWriter, r *http.Request) {\nfmt.Fprintf(w, \"Hello World!\")\n})\nhttp.ListenAndServe(\":80\", nil)\n}<\/code><\/pre>\n<p>\nDup\u0103 aceasta, dac\u0103 rula\u021bi aplica\u021bia \u0219i deschide\u021bi pagina <noindex>localhost<\/noindex>, ve\u021bi vedea imediat textul \u201eHello, world!\u201d (desigur, dac\u0103 totul func\u021bioneaz\u0103 corect).<\/p>\n<p>Apoi, vom folosi repetat handler-ul, dar mai \u00eent\u00e2i haide\u021bi s\u0103 \u00een\u021belegem cum func\u021bioneaz\u0103 totul.<\/p>\n<h4>net\/http<\/h4>\n<p>\n\u00cen exemplu a fost folosit pachetul <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/pkg\/net\/http\/\"><code>net\/http<\/code><\/a><\/noindex>, care este principalul instrument \u00een Go pentru dezvoltarea at\u00e2t a serverelor, c\u00e2t \u0219i a clien\u021bilor HTTP. Pentru a \u00een\u021belege codul, s\u0103 analiz\u0103m semnifica\u021bia a trei elemente importante: http.Handler, http.ServeMux \u0219i http.Server.<\/p>\n<h4>Handler-ele HTTP<\/h4>\n<p>\nC\u00e2nd primim o cerere, handler-ul o analizeaz\u0103 \u0219i genereaz\u0103 un r\u0103spuns. Handler-ele \u00een Go sunt implementate astfel:<\/p>\n<pre><code class=\"go\">type Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}<\/code><\/pre>\n<p>\n\u00cen primul exemplu se folose\u0219te func\u021bia utilitar\u0103 http.HandleFunc. Aceasta \u00eenv\u0103luie o alt\u0103 func\u021bie, care, la r\u00e2ndul s\u0103u, prime\u0219te http.ResponseWriter \u0219i http.Request \u00een ServeHTTP.<\/p>\n<p>Cu alte cuvinte, handler-ele \u00een Golang sunt reprezentate printr-un singur interfa\u021b\u0103, ceea ce ofer\u0103 numeroase oportunit\u0103\u021bi pentru programatori. De exemplu, middleware-ul este implementat printr-un handler, unde ServeHTTP ini\u021bial face ceva \u0219i apoi apeleaz\u0103 metoda ServeHTTP a altui handler.<\/p>\n<p>A\u0219a cum s-a men\u021bionat mai sus, handler-ele doar genereaz\u0103 r\u0103spunsuri la cereri. Dar ce handler specific trebuie utilizat \u00een fiecare moment?<\/p>\n<h4>Rutarea cererilor<\/h4>\n<p>\nPentru a face o alegere corect\u0103, utiliza\u021bi multiplexorul HTTP. \u00cen unele biblioteci, acesta este denumit muxer sau router, \u00eens\u0103 toate acestea se refer\u0103 la acela\u0219i lucru. Func\u021bia multiplexorului const\u0103 \u00een analizarea c\u0103ii cererii \u0219i alegerea handler-ului corespunz\u0103tor.<\/p>\n<p>Dac\u0103 ave\u021bi nevoie de suport pentru rutare complex\u0103, atunci este mai bine s\u0103 folosi\u021bi biblioteci externe. Unele dintre cele mai avansate sunt <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>, aceste biblioteci ofer\u0103 posibilitatea de a implementa tratarea intermediar\u0103 f\u0103r\u0103 probleme semnificative. Cu ajutorul lor, pute\u021bi configura rutare wildcard \u0219i realiza o serie de alte sarcini. Avantajul lor este compatibilitatea cu handler-ele HTTP standard. Ca rezultat, pute\u021bi scrie cod simplu cu posibilitatea de a-l modifica \u00een viitor.<\/p>\n<p>Lucrul cu framework-uri complexe \u00een situa\u021bii obi\u0219nuite va necesita solu\u021bii oarecum neobi\u0219nuite, ceea ce complic\u0103 semnificativ utilizarea handler-elor implicite. Pentru crearea celor mai multe aplica\u021bii, combina\u021bia dintre biblioteca implicit\u0103 \u0219i un router simplu este suficient\u0103.<\/p>\n<h4>Tratarea cererilor<\/h4>\n<p>\n\u00cen plus, avem nevoie de un component care s\u0103 \u201easculte\u201d conexiunile intrante \u0219i s\u0103 redirec\u021bioneze toate cererile c\u0103tre handler-ul corect. Acest lucru poate fi realizat cu u\u0219urin\u021b\u0103 prin http.Server.<\/p>\n<p>Mai jos este ar\u0103tat c\u0103 serverul este responsabil pentru toate sarcinile legate de tratarea conexiunilor. Acestea includ, de exemplu, lucrul cu protocolul TLS. Pentru a implementa apelul http.ListenAndServer, se folose\u0219te serverul HTTP standard.<\/p>\n<p>Acum haide\u021bi s\u0103 analiz\u0103m exemple mai complexe.<\/p>\n<h3>Ad\u0103ugarea Let\u2019s Encrypt<\/h3>\n<p>\n\u00cen mod implicit, aplica\u021bia noastr\u0103 func\u021bioneaz\u0103 pe protocolul HTTP, \u00eens\u0103 se recomand\u0103 utilizarea protocolului HTTPS. \u00cen Go, acest lucru se poate face f\u0103r\u0103 probleme. Dac\u0103 a\u021bi ob\u021binut un certificat \u0219i o cheie privat\u0103, atunci este suficient s\u0103 specifica\u021bi ListenAndServeTLS cu indicarea fi\u0219ierelor corecte pentru certificat \u0219i cheie.<\/p>\n<pre><code class=\"go\">http.ListenAndServeTLS(\":443\", \"cert.pem\", \"key.pem\", nil)<\/code><\/pre>\n<p>\n\u00centotdeauna se poate face mai bine.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a><\/noindex> ofer\u0103 certificate gratuite cu posibilitatea de actualizare automat\u0103. Pentru a folosi serviciul, ave\u021bi nevoie de pachetul <code>autocert<\/code>.<\/p>\n<p>Cel mai simplu mod de a-l configura este s\u0103 folosi\u021bi metoda autocert.NewListener \u00een combina\u021bie cu http.Serve. Metoda permite ob\u021binerea \u0219i actualizarea certificatelor TLS, \u00een timp ce serverul HTTP proceseaz\u0103 cererile:<\/p>\n<pre><code class=\"go\">http.Serve(autocert.NewListener(\"example.com\"), nil)<\/code><\/pre>\n<p>\nDac\u0103 deschidem \u00een browser <noindex><a rel=\"nofollow\" href=\"https:\/\/example.com\">example.com<\/a><\/noindex>, atunci vom ob\u021bine un r\u0103spuns HTTPS \u201eHello, world!\u201d\u3002<\/p>\n<p>Dac\u0103 ave\u021bi nevoie de o configurare mai detaliat\u0103, ar trebui s\u0103 folosi\u021bi managerul autocert.Manager. Apoi, cre\u0103m propria instan\u021b\u0103 http.Server (p\u00e2n\u0103 acum am folosit-o pe cea implicit\u0103) \u0219i ad\u0103ug\u0103m managerul \u00een server TLSConfig:<\/p>\n<pre><code class=\"go\">m := &amp;autocert.Manager{\nCache:      autocert.DirCache(\"golang-autocert\"),\nPrompt:     autocert.AcceptTOS,\nHostPolicy: autocert.HostWhitelist(\"example.org\", \"www.example.org\"),\n}\nserver := &amp;http.Server{\n    Addr:      \":443\",\n    TLSConfig: m.TLSConfig(),\n}\nserver.ListenAndServeTLS(\"\", \"\")<\/code><\/pre>\n<p>\nAceasta este o modalitate simpl\u0103 de a implementa suport complet pentru HTTPS cu actualizare automat\u0103 a certificatului.<\/p>\n<h3>Ad\u0103ugarea de rute personalizate<\/h3>\n<p>\nRouterul implicit, inclus \u00een biblioteca standard, este bun, dar foarte simplu. \u00cen majoritatea aplica\u021biilor, este necesar\u0103 o rutare mai complex\u0103, inclusiv rute imbricate \u0219i wildcard sau o procedur\u0103 de configurare a modelului \u0219i a parametrilor de cale.<\/p>\n<p>\u00cen acest caz, ar trebui s\u0103 folosi\u021bi pachetele <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> \u0219i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>. Cu acesta vom \u00eenv\u0103\u021ba s\u0103 lucr\u0103m \u2014 mai jos este un exemplu.<\/p>\n<p>Avem un fi\u0219ier api\/v1\/api.go, care con\u021bine rutele pentru API-ul nostru:<\/p>\n<pre><code class=\"go\">\/ HelloResponse is the JSON representation for a customized message\ntype HelloResponse struct {\nMessage string `json:\"message\"`\n}\n \n\/\/ HelloName returns a personalized JSON message\nfunc HelloName(w http.ResponseWriter, r *http.Request) {\nname := chi.URLParam(r, \"name\")\nresponse := HelloResponse{\nMessage: fmt.Sprintf(\"Hello %s!\", name),\n}\njsonResponse(w, response, http.StatusOK)\n}\n \n\/\/ NewRouter returns an HTTP handler that implements the routes for the API\nfunc NewRouter() http.Handler {\nr := chi.NewRouter()\nr.Get(\"\/{name}\", HelloName)\nreturn r\n}<\/code><\/pre>\n<p>\nSet\u0103m un prefix pentru rutele api\/vq \u00een fi\u0219ierul principal.<\/p>\n<p>Putem atunci s\u0103 le mont\u0103m pe routerul nostru principal sub prefixul api\/v1\/ \u00een aplica\u021bia principal\u0103:<\/p>\n<pre><code class=\"go\">\/\/ NewRouter returns a new HTTP handler that implements the main server routes\nfunc NewRouter() http.Handler {\nrouter := chi.NewRouter()\n    router.Mount(\"\/api\/v1\/\", v1.NewRouter())\n    return router\n}\nhttp.Serve(autocert.NewListener(\"example.com\"), NewRouter())<\/code><\/pre>\n<p>\nSimplitatea lucrului cu rutele complexe \u00een Go permite o structurare mai u\u0219oar\u0103 \u00een \u00eentre\u021binerea aplica\u021biilor mari \u0219i complexe.<\/p>\n<h3>Lucrul cu middleware<\/h3>\n<p>\n\u00cen cazul proces\u0103rii intermediare, este folosit\u0103 \u00eenvelirea unui handler HTTP de c\u0103tre altul, ceea ce permite o autentificare rapid\u0103, comprimare, jurnalizare \u0219i unele alte func\u021bii.<\/p>\n<p>Ca exemplu, s\u0103 lu\u0103m interfa\u021ba http.Handler, cu ajutorul c\u0103reia vom scrie un handler cu autentificarea utilizatorilor serviciului.<\/p>\n<pre><code class=\"go\">func RequireAuthentication(next http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n        if !isAuthenticated(r) {\n            http.Redirect(w, r, \"\/login\", http.StatusTemporaryRedirect)\n            return\n        }\n        \/\/ Presupun\u00e2nd c\u0103 autentificarea a fost aprobat\u0103, rula\u021bi handlerul original\n        next.ServeHTTP(w, r)\n    })\n}<\/code><\/pre>\n<p>\nExist\u0103 routere ter\u021be, cum ar fi chi, care permit extinderea func\u021bionalit\u0103\u021bii proces\u0103rii intermediare.<\/p>\n<h3>Lucrul cu fi\u0219iere statice<\/h3>\n<p>\nBiblioteca standard Go include func\u021bionalit\u0103\u021bi pentru a gestiona con\u021binutul static, inclusiv imagini, precum \u0219i fi\u0219iere JavaScript \u0219i CSS. Accesul la acestea se poate face prin func\u021bia http.FileServer. Aceasta returneaz\u0103 un handler care serve\u0219te fi\u0219iere dintr-un director specific.<\/p>\n<pre><code class=\"go\">func NewRouter() http.Handler {\n    router := chi.NewRouter()\n    r.Get(\"\/{name}\", HelloName)\n \n\/\/ Configurarea distribuirii fi\u0219ierelor statice\nstaticPath, _ := filepath.Abs(\"..\/..\/static\/\")\nfs := http.FileServer(http.Dir(staticPath))\n    router.Handle(\"\/*\", fs)\n    \n    return r<\/code><\/pre>\n<p>\nEste important s\u0103 re\u021bii c\u0103 http.Dir va afi\u0219a con\u021binutul unui director doar dac\u0103 nu exist\u0103 un fi\u0219ier index.html principal \u00een acesta. \u00cen acest caz, pentru a evita compromiterea directorului, ar trebui s\u0103 folose\u0219ti pachetul <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jordan-wright\/unindexed\"><code>neindexat<\/code><\/a><\/noindex>.<\/p>\n<h3>\u00cenchidere corect\u0103<\/h3>\n<p>\n\u00cen Go, exist\u0103 \u0219i o func\u021bie pentru \u00eenchiderea corect\u0103 a serverului HTTP. Acest lucru se poate face folosind metoda Shutdown(). Serverul porne\u0219te \u00eentr-o gorutin\u0103, iar apoi se ascult\u0103 un canal pentru a primi semnale de \u00eentrerupere. Odat\u0103 ce semnalul este primit, serverul se opre\u0219te, dar nu imediat, ci dup\u0103 c\u00e2teva secunde.<\/p>\n<pre><code class=\"go\">handler := server.NewRouter()\nsrv := &amp;http.Server{\n    Handler: handler,\n}\n \ngo func() {\nsrv.Serve(autocert.NewListener(domains...))\n}()\n \n\/\/ A\u0219teapt\u0103 o \u00eentrerupere\nc := make(chan os.Signal, 1)\nsignal.Notify(c, os.Interrupt)\n&lt;-c\n \n\/\/ \u00cencearc\u0103 o oprire gra\u021bioas\u0103\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nsrv.Shutdown(ctx)<\/code><\/pre>\n<p><\/p>\n<h3>\u00cen concluzie<\/h3>\n<p>\nGo este un limbaj puternic cu o bibliotec\u0103 standard practic universal\u0103. Capabilit\u0103\u021bile sale implicite sunt destul de vaste, iar acestea pot fi \u00eembun\u0103t\u0103\u021bite prin intermediul interfe\u021belor \u2014 ceea ce permite dezvoltarea de servere HTTP cu adev\u0103rat fiabile.<\/p>\n<blockquote><p><b>Skillbox recomand\u0103:<\/b><\/p>\n<ul>\n<li>Curs practic de doi ani <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/\">\u201eSunt un dezvoltator web PRO\u201d<\/a><\/noindex>.<\/li>\n<li>Curs online educa\u021bional <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/java\/\">\u00abProfesie Java Developer\u00bb<\/a><\/noindex>.<\/li>\n<li>Curs practic anual <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/\">\u00abDezvoltator PHP de la 0 la PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/skillbox\/blog\/446454\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u044f\u0442\u044c \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c Gophish, \u044d\u0442\u043e \u0434\u0430\u043b\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u0443\u0447\u0438\u0442\u044c Golang. \u042f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e Go \u2014 \u043c\u043e\u0449\u043d\u044b\u0439 \u044f\u0437\u044b\u043a, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a. Go \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u0435\u043d: \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 Go. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0432\u0435\u0449\u0435\u0439, \u0432\u0440\u043e\u0434\u0435 \u00abHello world!\u00bb, \u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0441 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22767,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-30782","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u044f\u0442\u044c \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u043d\u0430\u0447\u0430\u043b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u043d\u0430 Golang \u2014 \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a \u0441\u043b\u043e\u0436\u043d\u043e\u043c\u0443 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u044f\u0442\u044c \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u043d\u0430\u0447\u0430\u043b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:37:25+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:37:25+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Dezvoltarea serverelor web \u00een Golang \u2014 de la simplu la complex | ProHoster","description":"Acum cinci ani am \u00eenceput.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u043d\u0430 Golang \u2014 \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a \u0441\u043b\u043e\u0436\u043d\u043e\u043c\u0443 | ProHoster","og:description":"\u041f\u044f\u0442\u044c \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434 \u044f \u043d\u0430\u0447\u0430\u043b.","og:url":"https:\/\/prohoster.info\/ro\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:37:25+00:00","article:modified_time":"2019-10-31T18:37:25+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30782","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 02:59:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:29:56","updated":"2026-01-21 02:59:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/30782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=30782"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/30782\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/22767"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=30782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=30782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=30782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}