{"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\/it\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","title":{"rendered":"Sviluppo di server web in Golang \u2014 dal semplice al complesso","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Sviluppo di server web in Golang \u2014 dal semplice al complesso\" src=\"\/wp-content\/uploads\/2019\/04\/4ee879ad45f0ed192a15705e20ae00dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nCinque anni fa ho iniziato <noindex><a rel=\"nofollow\" href=\"https:\/\/getgophish.com\/\">a sviluppare Gophish<\/a><\/noindex>, questo mi ha dato l'opportunit\u00e0 di studiare Golang. Ho capito che Go \u00e8 un linguaggio potente, le cui capacit\u00e0 sono ampliate da molte librerie. Go \u00e8 versatile: in particolare, con esso \u00e8 possibile sviluppare applicazioni server senza problemi.<\/p>\n<p>Questo articolo \u00e8 dedicato alla scrittura di un server in Go. Iniziamo con cose semplici, come \"Hello world!\", e concludiamo con un'applicazione con le seguenti caratteristiche:<\/p>\n<p>\u2014 Utilizzo di Let's Encrypt per HTTPS.<br \/>\n\u2014 Funzionamento come router API.<br \/>\n\u2014 Lavorare con middleware.<br \/>\n\u2014 Gestione di file statici.<br \/>\n\u2014 Chiusura corretta dell'applicazione.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Skillbox consiglia:<\/b> Corso pratico <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\">\u00abSviluppatore Python da zero\u00bb<\/a><\/noindex>.<\/p>\n<p><b>Ricordiamo:<\/b> <i>per tutti i lettori di \u00abHabr\u00bb \u2014 sconto di 10.000 rubli per l'iscrizione a qualsiasi corso Skillbox con il codice promozionale \u00abHabr\u00bb.<\/i>\n<\/p><\/blockquote>\n<h3>Hello, world!<\/h3>\n<p>\nCreare un server web in Go \u00e8 molto veloce. Ecco un esempio di un gestore che restituisce il \"Hello, world!\" promesso sopra.<\/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>\nDopo di che, se avvi la applicazione e apri la pagina <noindex>localhost<\/noindex>, vedrai subito il testo \"Hello, world!\" (ovviamente, se tutto funziona correttamente).<\/p>\n<p>Successivamente utilizzeremo pi\u00f9 volte il gestore, ma prima facciamo chiarezza su come funziona tutto.<\/p>\n<h4>net\/http<\/h4>\n<p>\nNell'esempio \u00e8 stato utilizzato il pacchetto <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/pkg\/net\/http\/\"><code>net\/http<\/code><\/a><\/noindex>, questo \u00e8 lo strumento principale in Go per sviluppare sia server che client HTTP. Per comprendere il codice, analizziamo tre elementi importanti: http.Handler, http.ServeMux e http.Server.<\/p>\n<h4>I gestori HTTP<\/h4>\n<p>\nQuando riceviamo una richiesta, il gestore la analizza e formula una risposta. I gestori in Go sono implementati nel seguente modo:<\/p>\n<pre><code class=\"go\">type Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}<\/code><\/pre>\n<p>\nNel primo esempio viene utilizzata la funzione di supporto http.HandleFunc. Questa avvolge un'altra funzione che, a sua volta, accetta http.ResponseWriter e http.Request in ServeHTTP.<\/p>\n<p>In altre parole, i gestori in Golang sono rappresentati da un'unica interfaccia, il che offre molte possibilit\u00e0 per il programmatore. Ad esempio, il middleware \u00e8 implementato tramite un gestore, dove ServeHTTP prima fa qualcosa e poi chiama il metodo ServeHTTP di un altro gestore.<\/p>\n<p>Come detto sopra, i gestori semplicemente formulano risposte alle richieste. Ma quale gestore utilizzare in un dato momento?<\/p>\n<h4>Instradamento delle richieste<\/h4>\n<p>\nPer fare la scelta giusta, utilizza il multiplexing HTTP. In alcune librerie viene chiamato muxer o router, ma si tratta della stessa cosa. La funzione del multiplexore consiste nell'analizzare il percorso della richiesta e selezionare il gestore corrispondente.<\/p>\n<p>Se hai bisogno di supporto per una routing complessa, \u00e8 meglio utilizzare librerie esterne. Tra le pi\u00f9 avanzate ci sono <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>, queste librerie consentono di implementare il middleware senza particolari problemi. Con esse puoi configurare il routing wildcard e svolgere una serie di altre attivit\u00e0. Il loro vantaggio \u00e8 la compatibilit\u00e0 con i gestori HTTP standard. Di conseguenza, puoi scrivere codice semplice con la possibilit\u00e0 di modificarlo in futuro.<\/p>\n<p>Lavorare con framework complessi in una situazione normale richieder\u00e0 soluzioni non standard, il che rende significativamente pi\u00f9 difficile l'uso dei gestori predefiniti. Per creare la stragrande maggioranza delle applicazioni \u00e8 sufficiente una combinazione della libreria predefinita e di un router semplice.<\/p>\n<h4>Gestione delle richieste<\/h4>\n<p>\nInoltre, abbiamo bisogno di un componente che 'ascolti' le connessioni in entrata e indirizzi tutte le richieste al gestore corretto. Con questa funzione pu\u00f2 facilmente far fronte http.Server.<\/p>\n<p>Sotto \u00e8 mostrato che il server \u00e8 responsabile di tutte le attivit\u00e0 relative alla gestione delle connessioni. Questo include, ad esempio, il funzionamento tramite il protocollo TLS. Per attivare http.ListenAndServe viene utilizzato il server HTTP standard.<\/p>\n<p>Ora consideriamo esempi pi\u00f9 complessi.<\/p>\n<h3>Aggiungere Let\u2019s Encrypt<\/h3>\n<p>\nPer impostazione predefinita, la nostra applicazione funziona tramite il protocollo HTTP, ma si consiglia di utilizzare il protocollo HTTPS. In Go questo \u00e8 possibile senza problemi. Se hai ottenuto un certificato e una chiave privata, \u00e8 sufficiente specificare ListenAndServeTLS indicando i corretti file del certificato e della chiave.<\/p>\n<pre><code class=\"go\">http.ListenAndServeTLS(':443', 'cert.pem', 'key.pem', nil)<\/code><\/pre>\n<p>\nSi pu\u00f2 sempre fare meglio.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a><\/noindex> fornisce certificati gratuiti con possibilit\u00e0 di aggiornamento automatico. Per utilizzare questo servizio, \u00e8 necessario il pacchetto <code>autocert<\/code>.<\/p>\n<p>Il modo pi\u00f9 semplice per configurarlo \u00e8 usare il metodo autocert.NewListener in combinazione con http.Serve. Questo metodo consente di ottenere e aggiornare i certificati TLS, mentre il server HTTP gestisce le richieste:<\/p>\n<pre><code class=\"go\">http.Serve(autocert.NewListener('example.com'), nil)<\/code><\/pre>\n<p>\nSe apriamo nel browser <noindex><a rel=\"nofollow\" href=\"https:\/\/example.com\">example.com<\/a><\/noindex>, otterremo la risposta HTTPS \u00abHello, world!\u00bb.<\/p>\n<p>Se \u00e8 necessaria una configurazione pi\u00f9 dettagliata, \u00e8 consigliabile utilizzare il gestore autocert.Manager. Quindi creiamo una nostra istanza di http.Server (fino a questo momento abbiamo utilizzato quella predefinita) e aggiungiamo il gestore alla configurazione TLSConfig del server:<\/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>\nQuesto \u00e8 un modo semplice per implementare il pieno supporto HTTPS con aggiornamento automatico del certificato.<\/p>\n<h3>Aggiunta di rotte personalizzate<\/h3>\n<p>\nIl router predefinito incluso nella libreria standard \u00e8 buono, ma \u00e8 molto semplice. Nella maggior parte delle applicazioni \u00e8 necessaria una routing pi\u00f9 complesso, incluse rotte nidificate e wildcard, o anche una procedura per impostare modelli e parametri delle strade.<\/p>\n<p>In questo caso, \u00e8 opportuno utilizzare i pacchetti <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>. Con quest'ultimo impareremo a lavorare \u2014 di seguito \u00e8 mostrato un esempio.<\/p>\n<p>Dato \u2014 il file api\/v1\/api.go, contenente le rotte per la nostra API:<\/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>\nImpostiamo il prefisso delle rotte api\/v1 nel file principale.<\/p>\n<p>Possiamo quindi montare questo sul nostro router principale sotto il prefisso api\/v1 nella nostra applicazione principale:<\/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>\nLa semplicit\u00e0 di lavorare con rotte complesse in Go rende possibile semplificare la strutturazione della manutenzione di grandi applicazioni complesse.<\/p>\n<h3>Lavorare con middleware<\/h3>\n<p>\nNel caso del middleware, si utilizza l'incapsulamento di un gestore HTTP all'interno di un altro, il che consente di effettuare rapidamente autenticazione, compressione, logging e alcune altre funzionalit\u00e0.<\/p>\n<p>Come esempio, consideriamo l'interfaccia http.Handler, con essa scriveremo un gestore per l'autenticazione degli utenti del servizio.<\/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        \\\/\\\/ Assumendo che l'autenticazione sia passata, esegui il gestore originale\n        next.ServeHTTP(w, r)\n    })\n}<\/code><\/pre>\n<p>\nCi sono router di terze parti, come chi, che consentono di estendere le funzionalit\u00e0 del middleware.<\/p>\n<h3>Lavorare con file statici<\/h3>\n<p>\nLa libreria standard di Go include funzioni per lavorare con contenuti statici, comprese immagini, e file JavaScript e CSS. \u00c8 possibile accedervi attraverso la funzione http.FileServer. Questa restituisce un gestore che distribuisce file da una directory specificata.<\/p>\n<pre><code class=\"go\">func NewRouter() http.Handler {\n    router := chi.NewRouter()\n    r.Get(\"\/{name}\", HelloName)\n \n\/\/ Configurazione della distribuzione dei file statici\nstaticPath, _ := filepath.Abs(\"..\/\/..\/\/static\/\/\")\nfs := http.FileServer(http.Dir(staticPath))\n    router.Handle(\"\/*\", fs)\n    \n    return r<\/code><\/pre>\n<p>\n\u00c8 importante ricordare che http.Dir restituisce il contenuto della directory solo se non \u00e8 presente il file principale index.html. In questo caso, per evitare la compromissione della directory, \u00e8 opportuno utilizzare il pacchetto <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jordan-wright\/unindexed\"><code>non indicizzato<\/code><\/a><\/noindex>.<\/p>\n<h3>Chiusura corretta<\/h3>\n<p>\nIn Go esiste anche una funzione per la chiusura corretta del server HTTP. Questo pu\u00f2 essere fatto utilizzando il metodo Shutdown(). Il server viene avviato in una goroutine e successivamente un canale viene monitorato per ricevere un segnale di interruzione. Una volta ricevuto il segnale, il server si spegne, ma non immediatamente, bens\u00ec dopo alcuni secondi.<\/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\/\/ Attendere un'interruzione\nc := make(chan os.Signal, 1)\nsignal.Notify(c, os.Interrupt)\n&lt;-c\n \n\/\/ Tentativo di chiusura elegante\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nsrv.Shutdown(ctx)<\/code><\/pre>\n<p><\/p>\n<h3>In conclusione<\/h3>\n<p>\nGo \u00e8 un linguaggio potente con una libreria standard praticamente universale. Le sue funzionalit\u00e0 predefinite sono ampie e possono essere ampliate grazie alle interfacce, il che consente di sviluppare server HTTP realmente robusti.<\/p>\n<blockquote><p><b>Skillbox consiglia:<\/b><\/p>\n<ul>\n<li>Corso pratico di due anni <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/\">\u00abSono un web developer PRO\u00bb<\/a><\/noindex>.<\/li>\n<li>Corso online educativo <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/java\/\">\u00abProfessione Sviluppatore Java\u00bb<\/a><\/noindex>.<\/li>\n<li>Corso pratico annuale <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/\">\u00abSviluppatore PHP da 0 a PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Fonte: <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.1.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\/it\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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\/it\/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\udd47Sviluppo di server web in Golang \u2014 dal semplice al complesso | ProHoster","description":"Cinque anni fa ho iniziato.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/30782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=30782"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/30782\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/22767"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=30782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=30782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=30782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}