{"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\/sq\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","title":{"rendered":"Zhvillimi i server\u00ebve web n\u00eb Golang \u2014 nga e thjeshta n\u00eb t\u00eb komplikuar","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Zhvillimi i server\u00ebve web n\u00eb Golang \u2014 nga e thjeshta n\u00eb t\u00eb komplikuar\" src=\"\/wp-content\/uploads\/2019\/04\/4ee879ad45f0ed192a15705e20ae00dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nPes\u00eb vjet m\u00eb par\u00eb, fillova <noindex><a rel=\"nofollow\" href=\"https:\/\/getgophish.com\/\">t\u00eb zhvilloja Gophish<\/a><\/noindex>, kjo m\u00eb dha mund\u00ebsin\u00eb t\u00eb m\u00ebsoj Golang. Kuptova se Go \u00ebsht\u00eb nj\u00eb gjuh\u00eb e fuqishme, pavar\u00ebsisht mund\u00ebsive t\u00eb saj q\u00eb plot\u00ebsohen nga shum\u00eb biblioteka. Go \u00ebsht\u00eb universal: n\u00eb ve\u00e7anti, me t\u00eb mund t\u00eb zhvillosh pa probleme aplikacione serveri.<\/p>\n<p>Ky artikull i kushtohet zhvillimit t\u00eb nj\u00eb serveri n\u00eb Go. Le t\u00eb fillojm\u00eb me gj\u00ebrat e thjeshta, si \"P\u00ebrsh\u00ebndetje, bot\u00eb!\", dhe t\u00eb p\u00ebrfundojm\u00eb me nj\u00eb aplikacion q\u00eb ka k\u00ebto mund\u00ebsi:<\/p>\n<p>\u2014 P\u00ebrdorimi i Let\u2019s Encrypt p\u00ebr HTTPS.<br \/>\n\u2014 Funksionimi si nj\u00eb API router.<br \/>\n\u2014 Puna me middleware.<br \/>\n\u2014 Trajtimi i skedar\u00ebve statik\u00eb.<br \/>\n\u2014 Mbyllja e duhur.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Skillbox rekomandon:<\/b> Kurs praktik <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\">\"Zhvillues Python nga zero\"<\/a><\/noindex>.<\/p>\n<p><b>Kujtojm\u00eb:<\/b> <i>p\u00ebr t\u00eb gjith\u00eb lexuesit e \u00abHabra\u00bb \u2014 zbritje prej 10,000 rublesh p\u00ebr regjistrimin n\u00eb \u00e7do kurs Skillbox me kodin promovues \u00abHabr\u00bb.<\/i>\n<\/p><\/blockquote>\n<h3>P\u00ebrsh\u00ebndetje, bot\u00eb!<\/h3>\n<p>\nT\u00eb krijosh nj\u00eb server web n\u00eb Go \u00ebsht\u00eb shum\u00eb e shpejt\u00eb. Ja nj\u00eb shembull i p\u00ebrdorimit t\u00eb nj\u00eb trajtuesi q\u00eb kthen \"P\u00ebrsh\u00ebndetje, bot\u00eb!\" si\u00e7 u premtua m\u00eb par\u00eb.<\/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, \"P\u00ebrsh\u00ebndetje, bot\u00eb!\")\n})\nhttp.ListenAndServe(\":80\", nil)\n}<\/code><\/pre>\n<p>\nPas k\u00ebsaj, n\u00ebse e nisni aplikacionin dhe hapni faqen <noindex>localhost<\/noindex>, do t\u00eb shihni menj\u00ebher\u00eb tekstin \"P\u00ebrsh\u00ebndetje, bot\u00eb!\" (sigurisht, n\u00ebse gjith\u00e7ka funksionon si\u00e7 duhet).<\/p>\n<p>M\u00eb pas, do t\u00eb p\u00ebrdorim shpesh trajtuesin, por s\u00eb pari le t\u00eb kuptojm\u00eb se si funksionon gjith\u00e7ka.<\/p>\n<h4>net\/http<\/h4>\n<p>\nN\u00eb shembull u p\u00ebrdor paketa <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/pkg\/net\/http\/\"><code>net\/http<\/code><\/a><\/noindex>, kjo \u00ebsht\u00eb mjeti kryesor n\u00eb Go p\u00ebr zhvillimin e server\u00ebve dhe HTTP klient\u00ebve. P\u00ebr t\u00eb kuptuar kodin, le t\u00eb shqyrtojm\u00eb tri element\u00eb t\u00eb r\u00ebnd\u00ebsish\u00ebm: http.Handler, http.ServeMux dhe http.Server.<\/p>\n<h4>Trajtuesit HTTP<\/h4>\n<p>\nKur marrim nj\u00eb k\u00ebrkes\u00eb, trajtuesi e analizon at\u00eb dhe formon nj\u00eb p\u00ebrgjigje. Trajtuesit n\u00eb Go jan\u00eb realizuar n\u00eb k\u00ebt\u00eb m\u00ebnyr\u00eb:<\/p>\n<pre><code class=\"go\">type Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}<\/code><\/pre>\n<p>\nN\u00eb shembullin e par\u00eb p\u00ebrdoret funksioni ndihm\u00ebs http.HandleFunc. Ai mb\u00ebshtjell nj\u00eb funksion tjet\u00ebr, i cili, nga ana e tij, pranon http.ResponseWriter dhe http.Request n\u00eb ServeHTTP.<\/p>\n<p>Me fjal\u00eb t\u00eb tjera, trajtuesit n\u00eb Golang jan\u00eb t\u00eb p\u00ebrfaq\u00ebsuar nga nj\u00eb interface, q\u00eb ofron shum\u00eb mund\u00ebsi p\u00ebr programuesin. K\u00ebshtu, p\u00ebr shembull, middleware \u00ebsht\u00eb realizuar n\u00ebp\u00ebrmjet trajtuesit, ku ServeHTTP s\u00eb pari b\u00ebn di\u00e7ka, dhe m\u00eb pas th\u00ebrret metod\u00ebn ServeHTTP t\u00eb nj\u00eb trajtuesi tjet\u00ebr.<\/p>\n<p>Si\u00e7 u tha m\u00eb lart, trajtuesit thjesht formojn\u00eb p\u00ebrgjigje p\u00ebr k\u00ebrkesat. Por cili trajtues duhet t\u00eb p\u00ebrdorim n\u00eb nj\u00eb moment t\u00eb caktuar?<\/p>\n<h4>Routimi i k\u00ebrkesave<\/h4>\n<p>\nP\u00ebr t\u00eb b\u00ebr\u00eb nj\u00eb zgjedhje t\u00eb sakt\u00eb, p\u00ebrdorni shum\u00ebkaluar\u00ebsin HTTP. N\u00eb disa biblioteka ai quhet muxer ose router, por t\u00eb gjitha jan\u00eb e nj\u00ebjta gj\u00eb. Funksioni i shum\u00ebkaluar\u00ebsit \u00ebsht\u00eb t\u00eb analizoj\u00eb rrug\u00ebn e k\u00ebrkes\u00ebs dhe t\u00eb zgjedh\u00eb trajtuesin e duhur.<\/p>\n<p>N\u00ebse nevojitet mb\u00ebshtetje p\u00ebr routing t\u00eb komplikuar, at\u00ebher\u00eb \u00ebsht\u00eb m\u00eb mir\u00eb t\u00eb p\u00ebrdoren biblioteka t\u00eb jashtme. Disa nga m\u00eb t\u00eb avancuarat jan\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>, k\u00ebto biblioteka ofrojn\u00eb mund\u00ebsin\u00eb p\u00ebr t\u00eb realizuar p\u00ebrpunimin nd\u00ebrmjet\u00ebs pa shum\u00eb probleme. Me ndihm\u00ebn e tyre, mund t\u00eb konfigurohet routing me wildcard dhe t\u00eb realizohen nj\u00eb s\u00ebr\u00eb detyrash t\u00eb tjera. Avantazhi i tyre \u00ebsht\u00eb se jan\u00eb t\u00eb p\u00ebrputhshme me trajtuesit standard\u00eb HTTP. Si rezultat, mund t\u00eb shkruani kod t\u00eb thjesht\u00eb me mund\u00ebsi t\u00eb modifikimit n\u00eb t\u00eb ardhmen.<\/p>\n<p>Puna me framework t\u00eb komplikuara n\u00eb situata t\u00eb zakonshme do t\u00eb k\u00ebrkoj\u00eb zgjidhje jo standarde, gj\u00eb q\u00eb e komplikon ndjesh\u00ebm p\u00ebrdorimin e trajtuesve default. P\u00ebr krijimin e shumic\u00ebs d\u00ebrrmuese t\u00eb aplikacioneve mjafton nj\u00eb kombinim i bibliotek\u00ebs m\u00eb t\u00eb zakonshme dhe nj\u00eb router t\u00eb thjesht\u00eb.<\/p>\n<h4>P\u00ebrpunimi i k\u00ebrkesave<\/h4>\n<p>\nP\u00ebrve\u00e7 k\u00ebsaj, na nevojitet nj\u00eb komponent q\u00eb do t\u00eb \"d\u00ebgjoj\u00eb\" lidhjet q\u00eb vijn\u00eb dhe t\u00eb redirektoj\u00eb t\u00eb gjitha k\u00ebrkesat te trajtuesi i duhur. Me k\u00ebt\u00eb detyr\u00eb do t\u00eb p\u00ebrballet pa problemet http.Server.<\/p>\n<p>M\u00eb posht\u00eb tregohet se serveri \u00ebsht\u00eb p\u00ebrgjegj\u00ebs p\u00ebr t\u00eb gjitha detyrat q\u00eb kan\u00eb t\u00eb b\u00ebjn\u00eb me p\u00ebrpunimin e lidhjeve. Kjo, p\u00ebr shembull, p\u00ebrfshin pun\u00ebn sipas protokollit TLS. P\u00ebr realizimin e thirrjes http.ListenAndServer p\u00ebrdoret serveri standard HTTP.<\/p>\n<p>Tani le t\u00eb shqyrtojm\u00eb shembuj m\u00eb kompleks.<\/p>\n<h3>Shtimi i Let\u2019s Encrypt<\/h3>\n<p>\nP\u00ebr default, aplikacioni yn\u00eb punon sipas protokollit HTTP, megjithat\u00eb rekomandohet p\u00ebrdorimi i protokollit HTTPS. N\u00eb Go kjo mund t\u00eb b\u00ebhet pa probleme. N\u00ebse keni marr\u00eb nj\u00eb certifikat\u00eb dhe \u00e7el\u00ebs privat, at\u00ebher\u00eb mjafton t\u00eb shkruani ListenAndServeTLS me tregimin e skedar\u00ebve t\u00eb duhur t\u00eb certifikat\u00ebs dhe \u00e7el\u00ebsit.<\/p>\n<pre><code class=\"go\">http.ListenAndServeTLS(\":443\", \"cert.pem\", \"key.pem\", nil)<\/code><\/pre>\n<p>\nGjithmon\u00eb mund t\u00eb b\u00ebhet m\u00eb mir\u00eb.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a><\/noindex> ofron certifikata falas me mund\u00ebsin\u00eb e rinovimit automatik. P\u00ebr t\u00eb shfryt\u00ebzuar k\u00ebt\u00eb sh\u00ebrbim, nevojitet paketa <code>autocert<\/code>.<\/p>\n<p>M\u00ebnyra m\u00eb e thjesht\u00eb p\u00ebr ta konfiguruar at\u00eb \u2014 \u00ebsht\u00eb t\u00eb p\u00ebrdorni metod\u00ebn autocert.NewListener n\u00eb kombinim me http.Serve. Metoda lejon marrjen dhe rinovimin e certifikatave TLS, nd\u00ebrkoh\u00eb q\u00eb serveri HTTP p\u00ebrpunon k\u00ebrkesat:<\/p>\n<pre><code class=\"go\">http.Serve(autocert.NewListener(\"example.com\"), nil)<\/code><\/pre>\n<p>\nN\u00ebse e hapim n\u00eb shfletues <noindex><a rel=\"nofollow\" href=\"https:\/\/example.com\">example.com<\/a><\/noindex>, do t\u00eb marr\u00ebsh p\u00ebrgjigje HTTPS \"Hello, world!\".<\/p>\n<p>N\u00ebse nevojitet nj\u00eb konfigurim m\u00eb i detajuar, ka kuptim t\u00eb p\u00ebrdor\u00ebsh menaxherin autocert.Manager. M\u00eb pas krijojm\u00eb instanc\u00ebn ton\u00eb http.Server (deri m\u00eb tani e kemi p\u00ebrdorur at\u00eb si parazgjedhje) dhe e shtojm\u00eb menaxherin n\u00eb serverin 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>\nKy \u00ebsht\u00eb nj\u00eb m\u00ebnyr\u00eb e thjesht\u00eb p\u00ebr t\u00eb implementuar mb\u00ebshtetje t\u00eb plot\u00eb HTTPS me azhurnimin automatik t\u00eb certifikat\u00ebs.<\/p>\n<h3>Shtimi i rrug\u00ebve jo standarde<\/h3>\n<p>\nRruga e parazgjedhur, e cila \u00ebsht\u00eb e p\u00ebrfshir\u00eb n\u00eb bibliotek\u00ebn standarde, \u00ebsht\u00eb e mir\u00eb, por \u00ebsht\u00eb shum\u00eb e thjesht\u00eb. N\u00eb shumic\u00ebn e aplikacioneve nevojitet nj\u00eb rrug\u00ebzim m\u00eb kompleks, duke p\u00ebrfshir\u00eb rrug\u00eb t\u00eb brendshme dhe wildcard ose procedur\u00ebn e vendosjes s\u00eb pamjeve dhe parametrave t\u00eb rrug\u00ebve.<\/p>\n<p>N\u00eb k\u00ebt\u00eb rast ka kuptim t\u00eb p\u00ebrdoren paketat <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>. Me t\u00eb fundit do t\u00eb m\u00ebsojm\u00eb t\u00eb punojm\u00eb - m\u00eb posht\u00eb \u00ebsht\u00eb nj\u00eb shembull.<\/p>\n<p>I dh\u00ebn\u00eb - file api\/v1\/api.go, q\u00eb p\u00ebrmban rrug\u00ebt p\u00ebr API-n\u00eb ton\u00eb:<\/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>\nCaktimi i prefiksit api\/vq p\u00ebr rrug\u00ebt n\u00eb skedarin kryesor.<\/p>\n<p>Mund ta ngjisim k\u00ebt\u00eb n\u00eb routerin ton\u00eb kryesor n\u00ebn prefiksin api\/v1 n\u00eb aplikacionin ton\u00eb kryesor:<\/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>\nThjesht\u00ebsia e pun\u00ebs me rrug\u00eb t\u00eb komplikuara n\u00eb Go e b\u00ebn t\u00eb mundur thjeshtimin e strukturimit me mb\u00ebshtetje p\u00ebr aplikacione t\u00eb m\u00ebdha dhe komplekse.<\/p>\n<h3>Puna me middleware<\/h3>\n<p>\nN\u00eb rastin e p\u00ebrpunimit t\u00eb nd\u00ebrmjet\u00ebm, nj\u00eb HTTP-handler i mb\u00ebshtjell\u00eb nga nj\u00eb tjet\u00ebr b\u00ebhet e mundur p\u00ebr t\u00eb kryer shpejt autentifikimin, kompresimin, regjistrimin dhe disa funksione t\u00eb tjera.<\/p>\n<p>Si shembull, le t\u00eb shqyrtojm\u00eb nd\u00ebrfaqen http.Handler, me ndihm\u00ebn e s\u00eb cil\u00ebs do t\u00eb shkruajm\u00eb nj\u00eb handler me autentifikimin e p\u00ebrdoruesve t\u00eb sh\u00ebrbimit.<\/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        \\\/\\\/ Supozoni se autentifikimi kaloi, ekzekutoni handler-in origjinal\n        next.ServeHTTP(w, r)\n    })\n}<\/code><\/pre>\n<p>\nEkzistojn\u00eb router\u00eb t\u00eb tjer\u00eb, si chi, t\u00eb cil\u00ebt lejojn\u00eb zgjerimin e funksionalitetit t\u00eb p\u00ebrpunimit t\u00eb nd\u00ebrmjet\u00ebm.<\/p>\n<h3>Puna me skedar\u00ebt statik\u00eb<\/h3>\n<p>\nBiblioteka standarde Go p\u00ebrmban mund\u00ebsi p\u00ebr t\u00eb punuar me p\u00ebrmbajtje statistik\u00eb, duke p\u00ebrfshir\u00eb imazhe, si dhe skedar\u00eb JavaScript dhe CSS. Praksesat mund t\u00eb arrihen p\u00ebrmes funksionit http.FileServer. Ajo kthen nj\u00eb handler q\u00eb shp\u00ebrndan skedar\u00eb nga nj\u00eb direktori e caktuar.<\/p>\n<pre><code class=\"go\">func NewRouter() http.Handler {\n    router := chi.NewRouter()\n    r.Get(\"\/{name}\", HelloName)\n \n\/\/ Konfigurimi i sh\u00ebrbimit t\u00eb skedar\u00ebve statik\u00eb\nstaticPath, _ := filepath.Abs(\"..\/..\/static\/\")\nfs := http.FileServer(http.Dir(staticPath))\n    router.Handle(\"\/*\", fs)\n    \n    return r<\/code><\/pre>\n<p>\n\u00cbsht\u00eb e r\u00ebnd\u00ebsishme t\u00eb kujtojm\u00eb se http.Dir tregon p\u00ebrmbajtjen e katalogut vet\u00ebm n\u00eb rast se nuk ka skedarin kryesor index.html. N\u00eb k\u00ebt\u00eb rast, p\u00ebr t\u00eb mos e lejuar kompromisimin e katalogut, \u00ebsht\u00eb e nevojshme t\u00eb p\u00ebrdorim paket\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jordan-wright\/unindexed\"><code>pa indeksuar<\/code><\/a><\/noindex>.<\/p>\n<h3>Mbyllje e sakt\u00eb<\/h3>\n<p>\nN\u00eb Go ekziston dhe nj\u00eb funksion p\u00ebr mbyllje t\u00eb sakt\u00eb t\u00eb serverit HTTP. Kjo mund t\u00eb b\u00ebhet p\u00ebrmes metod\u00ebs Shutdown(). Serveri niset n\u00eb nj\u00eb gorutin\u00eb, dhe pastaj kanali d\u00ebgjon p\u00ebr marrjen e nj\u00eb sinjali nd\u00ebrprerjeje. Sa her\u00eb q\u00eb merret sinjali, serveri mbyllet, por jo menj\u00ebher\u00eb, por pas disa sekondash.<\/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\/\/ Prit p\u00ebr nj\u00eb nd\u00ebrprerje\nc := make(chan os.Signal, 1)\nsignal.Notify(c, os.Interrupt)\n&lt;-c\n \n\/\/ P\u00ebrpiqu p\u00ebr nj\u00eb mbyllje t\u00eb sakt\u00eb\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nsrv.Shutdown(ctx)<\/code><\/pre>\n<p><\/p>\n<h3>N\u00eb p\u00ebrfundim<\/h3>\n<p>\nGo \u2014 nj\u00eb gjuh\u00eb e fuqishme me pothuajse nj\u00eb bibliotek\u00eb standarde universale. Mund\u00ebsit\u00eb e saj t\u00eb paracaktuara jan\u00eb shum\u00eb t\u00eb gjera, dhe ato mund t\u00eb p\u00ebrmir\u00ebsohen p\u00ebrmes nd\u00ebrfaqeve \u2014 kjo lejon zhvillimin e server\u00ebve HTTP v\u00ebrtet t\u00eb besuesh\u00ebm.<\/p>\n<blockquote><p><b>Skillbox rekomandon:<\/b><\/p>\n<ul>\n<li>Kursi praktik dyvje\u00e7ar <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/\">\u00abUn\u00eb jam zhvillues web PRO\u00bb<\/a><\/noindex>.<\/li>\n<li>Kurs online edukativ <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/java\/\">\u00abProfesia Java-zhvillues\u00bb<\/a><\/noindex>.<\/li>\n<li>Kurs praktik nj\u00ebvje\u00e7ar <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/\">\u00abZhvillues PHP nga 0 n\u00eb PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Burimi: <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\/sq\/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=\"sq_AL\" \/>\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\/sq\/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\udd47Zhvillimi i server\u00ebve web n\u00eb Golang \u2014 nga e thjeshta n\u00eb t\u00eb komplikuar | ProHoster","description":"Pes\u00eb vjet m\u00eb par\u00eb fillova.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","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\/sq\/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\/sq\/wp-json\/wp\/v2\/posts\/30782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=30782"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/30782\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/22767"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=30782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=30782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=30782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}