{"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\/da\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","title":{"rendered":"Udvikling af webservere p\u00e5 Golang - fra simpel til kompleks","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Udvikling af webservere p\u00e5 Golang - fra simpel til kompleks\" src=\"\/wp-content\/uploads\/2019\/04\/4ee879ad45f0ed192a15705e20ae00dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nFor fem \u00e5r siden begyndte jeg <noindex><a rel=\"nofollow\" href=\"https:\/\/getgophish.com\/\">at udvikle Gophish<\/a><\/noindex>, det gav mig mulighed for at l\u00e6re Golang. Jeg inds\u00e5, at Go er et kraftfuldt sprog, hvis muligheder supplerer et v\u00e6ld af biblioteker. Go er alsidigt: specielt kan det bruges til let at udvikle serverapplikationer.<\/p>\n<p>Denne artikel handler om at skrive en server i Go. Vi starter med enkle elementer, s\u00e5som 'Hello world!', og afslutter med en applikation med f\u00f8lgende funktioner:<\/p>\n<p>\u2014 Anvendelse af Let\u2019s Encrypt til HTTPS.<br \/>\n\u2014 Funktionere som API-router.<br \/>\n\u2014 Arbejde med middleware.<br \/>\n\u2014 H\u00e5ndtering af statiske filer.<br \/>\n\u2014 Korrekt nedlukning.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Skillbox anbefaler:<\/b> Praktisk kursus <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\">\u00abPython-udvikler fra bunden\u00bb<\/a><\/noindex>.<\/p>\n<p><b>Vi minder om:<\/b> <i>til alle l\u00e6sere af 'Habr' \u2014 rabat p\u00e5 10.000 rubler ved tilmelding til et hvilket som helst Skillbox-kursus med rabatkoden 'Habr'.<\/i>\n<\/p><\/blockquote>\n<h3>Hello, world!<\/h3>\n<p>\nDet er meget hurtigt at oprette en webserver i Go. Her er et eksempel p\u00e5 en handler, der returnerer den lovede 'Hello, world!'.<\/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>\nEfter dette, hvis du k\u00f8rer applikationen og \u00e5bner siden <noindex>localhost<\/noindex>, vil du straks se teksten 'Hello, world!' (naturligvis, hvis alt fungerer korrekt).<\/p>\n<p>Herefter vil vi flere gange bruge handleren, men f\u00f8rst lad os forst\u00e5, hvordan det hele fungerer.<\/p>\n<h4>net\/http<\/h4>\n<p>\nI eksemplet blev pakken <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/pkg\/net\/http\/\"><code>net\/http<\/code><\/a><\/noindex>, som er det prim\u00e6re v\u00e6rkt\u00f8j i Go til udvikling af b\u00e5de servere og HTTP-klienter. For at forst\u00e5 koden, lad os se p\u00e5 betydningen af tre vigtige elementer: http.Handler, http.ServeMux og http.Server.<\/p>\n<h4>HTTP-handlere<\/h4>\n<p>\nN\u00e5r vi modtager en anmodning, analyserer handleren den og formidler et svar. Handlere i Go implementeres s\u00e5ledes:<\/p>\n<pre><code class=\"go\">type Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}<\/code><\/pre>\n<p>\nI det f\u00f8rste eksempel bruges hj\u00e6lpefunktionen http.HandleFunc. Den indkapsler en anden funktion, som igen modtager http.ResponseWriter og http.Request i ServeHTTP.<\/p>\n<p>Med andre ord er handlere i Golang repr\u00e6senteret af et f\u00e6lles interface, hvilket giver programm\u00f8ren mange muligheder. S\u00e5ledes er middleware implementeret ved hj\u00e6lp af en handler, hvor ServeHTTP f\u00f8rst g\u00f8r noget, og derefter kalder metoden ServeHTTP for en anden handler.<\/p>\n<p>Som n\u00e6vnt tidligere, danner handlere blot svar p\u00e5 anmodninger. Men hvilken specifik handler skal bruges p\u00e5 et givet tidspunkt?<\/p>\n<h4>Routing af anmodninger<\/h4>\n<p>\nFor making the right choice, use the HTTP multiplexer. In several libraries, it is called a muxer or router, but they are all the same. The function of the multiplexer is to analyze the request path and select the appropriate handler.<\/p>\n<p>If support for complex routing is needed, it is better to use third-party libraries. Some of the most advanced are <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>, these libraries allow for middleware processing without any problems. With them, you can set up wildcard routing and perform a number of other tasks. Their advantage is compatibility with standard HTTP handlers. As a result, you can write simple code with the ability to modify it in the future.<\/p>\n<p>Working with complex frameworks usually requires somewhat non-standard solutions, which significantly complicates the use of default handlers. For creating the overwhelming majority of applications, a combination of the default library and a simple router is sufficient.<\/p>\n<h4>Request processing<\/h4>\n<p>\nIn addition, we need a component that will 'listen' for incoming connections and redirect all requests to the correct handler. This task can easily be handled by http.Server.<\/p>\n<p>Below is shown that the server is responsible for all tasks related to connection processing. This includes working with the TLS protocol. The standard HTTP server is used to implement http.ListenAndServer.<\/p>\n<p>Now let's look at more complex examples.<\/p>\n<h3>Adding Let\u2019s Encrypt<\/h3>\n<p>\nBy default, our application runs over the HTTP protocol, but it is recommended to use the HTTPS protocol. In Go, this can be done without problems. If you have obtained a certificate and a private key, it is sufficient to write ListenAndServeTLS with the correct certificate and key files specified.<\/p>\n<pre><code class=\"go\">http.ListenAndServeTLS(\":443\", \"cert.pem\", \"key.pem\", nil)<\/code><\/pre>\n<p>\nThere is always room for improvement.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a><\/noindex> provides free certificates with the possibility of automatic renewal. To use the service, the package is needed <code>autocert<\/code>.<\/p>\n<p>The simplest way to set it up is to use the autocert.NewListener method in combination with http.Serve. The method allows obtaining and updating TLS certificates while the HTTP server processes requests:<\/p>\n<pre><code class=\"go\">http.Serve(autocert.NewListener(\"example.com\"), nil)<\/code><\/pre>\n<p>\nIf we open in the browser <noindex><a rel=\"nofollow\" href=\"https:\/\/example.com\">example.com<\/a><\/noindex>, vi f\u00e5r HTTPS-svaret \u00abHello, world!\u00bb.<\/p>\n<p>Hvis der er behov for mere pr\u00e6cis konfiguration, b\u00f8r man bruge autocert.Manager. Derefter opretter vi vores egen instans af http.Server (indtil nu har vi brugt standardvarianten) og tilf\u00f8jer manageren til serverens 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>\nDette er en simpel metode til at implementere fuld st\u00f8tte til HTTPS med automatisk opdatering af certifikatet.<\/p>\n<h3>Tilf\u00f8jelse af ikke-standardruter<\/h3>\n<p>\nDen standardrouter, der er inkluderet i standardbiblioteket, er god, men den er meget simpel. De fleste applikationer har brug for mere kompleks routing, herunder indlejrede og wildcard-ruter eller en procedure for at ops\u00e6tte skabeloner og sti-parametre.<\/p>\n<p>I dette tilf\u00e6lde b\u00f8r man bruge pakker <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> og <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>. Med den sidstn\u00e6vnte vil vi l\u00e6re at arbejde \u2014 nedenfor er et eksempel.<\/p>\n<p>Givet \u2014 filen api\/v1\/api.go, der indeholder ruter for vores 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>\nVi s\u00e6tter et pr\u00e6fiks api\/vq for ruterne i hovedfilen.<\/p>\n<p>Vi kan derefter montere dette til vores hovedrouter under api\/v1\/-pr\u00e6fikset tilbage i vores hovedapplikation:<\/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>\nDen enkle h\u00e5ndtering af komplekse ruter i Go g\u00f8r det muligt at simplificere strukturen ved vedligeholdelse af store, komplekse applikationer.<\/p>\n<h3>Arbejde med middleware<\/h3>\n<p>\nI tilf\u00e6lde af mellemliggende behandling bruges omsluttende en HTTP-handler med en anden, hvilket muligg\u00f8r hurtig autentificering, komprimering, logf\u00f8ring og nogle andre funktioner.<\/p>\n<p>Som eksempel ser vi p\u00e5 http.Handler-gr\u00e6nsefladen, som vi bruger til at skrive en handler med autentificering af tjeneste brugere.<\/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        \/\/ Antager at autentificering er best\u00e5et, k\u00f8r den oprindelige handler\n        next.ServeHTTP(w, r)\n    })\n}<\/code><\/pre>\n<p>\nDer er tredjeparts-rutere, s\u00e5som chi, der tilbyder udvidet funktionalitet til mellemliggende behandling.<\/p>\n<h3>Arbejder med statiske filer<\/h3>\n<p>\nStandardbiblioteket i Go indeholder funktioner til at arbejde med statisk indhold, herunder billeder samt JavaScript- og CSS-filer. Adgang til dem kan f\u00e5s gennem funktionen http.FileServer. Den returnerer en handler, der serverer filer fra et bestemt bibliotek.<\/p>\n<pre><code class=\"go\">func NewRouter() http.Handler {\n    router := chi.NewRouter()\n    r.Get(\"\/{name}\", HelloName)\n \n\/\/ Konfigurering af statiske filfordelinger\nstaticPath, _ := filepath.Abs(\"..\/\/..\/\/static\/\/\")\nfs := http.FileServer(http.Dir(staticPath))\n    router.Handle(\"\/*\", fs)\n    \n    return r<\/code><\/pre>\n<p>\nDet er vigtigt at huske, at http.Dir viser indholdet af en mappe, hvis der ikke er nogen hovedfil index.html. I s\u00e5 fald, for at undg\u00e5 kompromittering af mappen, b\u00f8r pakken anvendes <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jordan-wright\/unindexed\"><code>uindekseret<\/code><\/a><\/noindex>.<\/p>\n<h3>Korrekt afslutning af arbejdet<\/h3>\n<p>\nI Go er der ogs\u00e5 en funktion til korrekt afslutning af en HTTP-server. Dette kan g\u00f8res ved hj\u00e6lp af metoden Shutdown(). Serveren k\u00f8rer i en goroutine, og kanalen lytter derefter efter afbrydelsessignaler. S\u00e5 snart signalet er modtaget, slukkes serveren, men ikke straks, men efter et par sekunder.<\/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\/\/ Vent p\u00e5 et afbrudt signal\nc := make(chan os.Signal, 1)\nsignal.Notify(c, os.Interrupt)\n&lt;-c\n \n\/\/ Fors\u00f8g en effektiv nedlukning\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefers cancel()\nsrv.Shutdown(ctx)<\/code><\/pre>\n<p><\/p>\n<h3>Som konklusion<\/h3>\n<p>\nGo \u2014 et kraftfuldt sprog med en n\u00e6sten universel standardbibliotek. Dens standardfunktioner er ret omfattende, og de kan styrkes ved hj\u00e6lp af gr\u00e6nseflader \u2014 dette muligg\u00f8r udvikling af virkelig p\u00e5lidelige HTTP-servere.<\/p>\n<blockquote><p><b>Skillbox anbefaler:<\/b><\/p>\n<ul>\n<li>To\u00e5rigt praktisk kursus <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/\">\u00abJeg er webudvikler PRO\u00bb<\/a><\/noindex>.<\/li>\n<li>Online uddannelseskursus <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/java\/\">\u00abJava-udvikler erhverv\u00bb<\/a><\/noindex>.<\/li>\n<li>Praktisk \u00e5rs kursus <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/\">\"PHP-udvikler fra 0 til PRO\"<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Kilde: <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.3 - 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\/da\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47Udvikling af webservere i Golang \u2014 fra simpel til kompleks | ProHoster","description":"For fem \u00e5r siden begyndte jeg.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/30782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=30782"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/30782\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/22767"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=30782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=30782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=30782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}