{"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\/es\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","title":{"rendered":"Desarrollo de servidores web en Golang \u2014 de lo simple a lo complejo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Desarrollo de servidores web en Golang \u2014 de lo simple a lo complejo\" src=\"\/wp-content\/uploads\/2019\/04\/4ee879ad45f0ed192a15705e20ae00dd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nHace cinco a\u00f1os comenc\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/getgophish.com\/\">a desarrollar Gophish<\/a><\/noindex>, lo que me dio la oportunidad de aprender Golang. Me di cuenta de que Go es un lenguaje poderoso, cuyas capacidades se complementan con muchas bibliotecas. Go es vers\u00e1til: en particular, se pueden desarrollar f\u00e1cilmente aplicaciones del lado del servidor.<\/p>\n<p>Este art\u00edculo se dedica a escribir un servidor en Go. Comenzaremos con cosas simples, como \u00ab\u00a1Hola, mundo!\u00bb, y terminaremos con una aplicaci\u00f3n que tenga las siguientes capacidades:<\/p>\n<p>\u2014 Uso de Let's Encrypt para HTTPS.<br \/>\n\u2014 Funciona como enrutador API.<br \/>\n\u2014 Trabaja con middleware.<br \/>\n\u2014 Manejo de archivos est\u00e1ticos.<br \/>\n\u2014 Finalizaci\u00f3n adecuada.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Skillbox recomienda:<\/b> Curso pr\u00e1ctico <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\">\u00abDesarrollador de Python desde cero\u00bb<\/a><\/noindex>.<\/p>\n<p><b>Recordamos:<\/b> <i>para todos los lectores de \u00abHabr\u00bb \u2014 un descuento de 10,000 rublos al registrarse en cualquier curso de Skillbox usando el c\u00f3digo promocional \u00abHabr\u00bb.<\/i>\n<\/p><\/blockquote>\n<h3>\u00a1Hola, mundo!<\/h3>\n<p>\nSe puede crear un servidor web en Go muy r\u00e1pidamente. Aqu\u00ed hay un ejemplo de un manejador que devuelve el mencionado \u00ab\u00a1Hola, mundo!\u00bb.<\/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, \"\u00a1Hola, Mundo!\")\n})\nhttp.ListenAndServe(\":80\", nil)\n}<\/code><\/pre>\n<p>\nDespu\u00e9s de esto, si inicias la aplicaci\u00f3n y abres la p\u00e1gina <noindex>localhost<\/noindex>, ver\u00e1s de inmediato el texto \u00ab\u00a1Hola, mundo!\u00bb (por supuesto, si todo funciona correctamente).<\/p>\n<p>A partir de aqu\u00ed, utilizaremos el manejador repetidamente, pero primero comprendamos c\u00f3mo funciona todo.<\/p>\n<h4>net\/http<\/h4>\n<p>\nEn el ejemplo se utiliz\u00f3 el paquete <noindex><a rel=\"nofollow\" href=\"https:\/\/golang.org\/pkg\/net\/http\/\"><code>net\/http<\/code><\/a><\/noindex>, que es la herramienta principal en Go para desarrollar tanto servidores como clientes HTTP. Para entender el c\u00f3digo, analicemos el significado de tres elementos importantes: http.Handler, http.ServeMux y http.Server.<\/p>\n<h4>Manejadores HTTP<\/h4>\n<p>\nCuando recibimos una solicitud, el manejador la analiza y forma una respuesta. Los manejadores en Go se implementan de la siguiente manera:<\/p>\n<pre><code class=\"go\">type Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}<\/code><\/pre>\n<p>\nEn el primer ejemplo se utiliza la funci\u00f3n auxiliar http.HandleFunc. Esta envuelve otra funci\u00f3n que, a su vez, recibe http.ResponseWriter y http.Request en ServeHTTP.<\/p>\n<p>En otras palabras, los manejadores en Golang est\u00e1n representados por una \u00fanica interfaz, lo que ofrece muchas posibilidades para el programador. Por ejemplo, el middleware se implementa mediante un manejador, donde ServeHTTP primero hace algo y luego llama al m\u00e9todo ServeHTTP de otro manejador.<\/p>\n<p>Como se mencion\u00f3 anteriormente, los manejadores simplemente generan respuestas a solicitudes. Pero, \u00bfqu\u00e9 manejador espec\u00edfico se debe usar en un momento determinado?<\/p>\n<h4>Enrutamiento de solicitudes<\/h4>\n<p>\nPara tomar la decisi\u00f3n correcta, utilice un multiplexor HTTP. En varias bibliotecas, se le denomina muxer o router, pero todo es lo mismo. La funci\u00f3n del multiplexor consiste en analizar la ruta de la solicitud y seleccionar el manejador correspondiente.<\/p>\n<p>Si se necesita soporte para enrutamiento complejo, entonces es mejor utilizar bibliotecas de terceros. Algunas de las m\u00e1s avanzadas son <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> y <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>, estas bibliotecas permiten implementar el procesamiento intermedio sin problemas. Con su ayuda, se puede configurar el enrutamiento con comodines y realizar varias otras tareas. Su ventaja es la compatibilidad con los manejadores HTTP est\u00e1ndares. Como resultado, puede escribir un c\u00f3digo simple con la posibilidad de modificarlo en el futuro.<\/p>\n<p>Trabajar con marcos complejos en situaciones normales requerir\u00e1 soluciones no est\u00e1ndar, lo cual complica significativamente el uso de manejadores predeterminados. Para crear la mayor\u00eda de las aplicaciones, basta con una combinaci\u00f3n de la biblioteca por defecto y un enrutador sencillo.<\/p>\n<h4>Procesamiento de solicitudes<\/h4>\n<p>\nAdem\u00e1s, necesitamos un componente que 'escuche' las conexiones entrantes y redirija todas las solicitudes al manejador correcto. Esta tarea la puede llevar a cabo sin dificultad http.Server.<\/p>\n<p>A continuaci\u00f3n se muestra que el servidor es responsable de todas las tareas relacionadas con el procesamiento de conexiones. Esto incluye, por ejemplo, el trabajo con el protocolo TLS. Para implementar la llamada http.ListenAndServer se utiliza el servidor HTTP est\u00e1ndar.<\/p>\n<p>Ahora revisemos ejemplos m\u00e1s complejos.<\/p>\n<h3>Adici\u00f3n de Let\u2019s Encrypt<\/h3>\n<p>\nPor defecto, nuestra aplicaci\u00f3n opera con el protocolo HTTP; sin embargo, se recomienda utilizar el protocolo HTTPS. En Go, esto se puede hacer sin problemas. Si ha obtenido un certificado y una clave privada, entonces es suficiente con especificar ListenAndServeTLS indicando los archivos de certificado y clave correctos.<\/p>\n<pre><code class=\"go\">http.ListenAndServeTLS(\":443\", \"cert.pem\", \"key.pem\", nil)<\/code><\/pre>\n<p>\nSiempre se puede hacer mejor.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a><\/noindex> ofrece certificados gratuitos con la posibilidad de actualizaciones autom\u00e1ticas. Para utilizar el servicio, se necesita el paquete <code>autocert<\/code>.<\/p>\n<p>La forma m\u00e1s sencilla de configurarlo es utilizar el m\u00e9todo autocert.NewListener en combinaci\u00f3n con http.Serve. El m\u00e9todo permite obtener y actualizar certificados TLS, mientras que el servidor HTTP maneja las solicitudes:<\/p>\n<pre><code class=\"go\">http.Serve(autocert.NewListener(\"example.com\"), nil)<\/code><\/pre>\n<p>\nSi abrimos en el navegador <noindex><a rel=\"nofollow\" href=\"https:\/\/example.com\">example.com<\/a><\/noindex>, entonces obtendremos una respuesta HTTPS \u00abHello, world!\u00bb.<\/p>\n<p>Si se necesita una configuraci\u00f3n m\u00e1s detallada, es conveniente utilizar el gestor autocert.Manager. A continuaci\u00f3n, creamos nuestra propia instancia http.Server (hasta ahora hemos utilizado la predeterminada) y a\u00f1adimos el gestor a la configuraci\u00f3n TLS del servidor:<\/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>\nEsta es una forma sencilla de implementar soporte completo para HTTPS con renovaci\u00f3n autom\u00e1tica del certificado.<\/p>\n<h3>A\u00f1adiendo rutas personalizadas<\/h3>\n<p>\nEl enrutador predeterminado incluido en la biblioteca est\u00e1ndar es bueno, pero es muy simple. En la mayor\u00eda de las aplicaciones, se necesita una enrutaci\u00f3n m\u00e1s compleja, incluyendo enrutamientos anidados y comodines o bien un procedimiento para establecer plantillas y par\u00e1metros de rutas.<\/p>\n<p>En este caso, vale la pena utilizar paquetes <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/gorilla\/mux\">gorilla\/mux<\/a><\/noindex> y <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-chi\/chi\">go-chi\/chi<\/a><\/noindex>. Con este \u00faltimo aprenderemos a trabajar \u2014 a continuaci\u00f3n se muestra un ejemplo.<\/p>\n<p>Dado \u2014 el archivo api\/v1\/api.go, que contiene las rutas para nuestra 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>\nEstablecemos un prefijo para las rutas api\/vq en el archivo principal.<\/p>\n<p>Podemos montarlo en nuestro enrutador principal bajo el prefijo api\/v1\/ de vuelta en nuestra aplicaci\u00f3n principal:<\/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 simplicidad en el manejo de rutas complejas en Go permite simplificar la estructuraci\u00f3n al mantener grandes aplicaciones complejas.<\/p>\n<h3>Trabajo con middleware<\/h3>\n<p>\nEn el caso de la intermediaci\u00f3n, se utiliza un envolvimiento de un manejador HTTP dentro de otro, lo que permite realizar r\u00e1pidamente autenticaci\u00f3n, compresi\u00f3n, registro y algunas otras funciones.<\/p>\n<p>Como ejemplo, consideremos la interfaz http.Handler, con la que escribiremos un manejador de autenticaci\u00f3n de usuarios del servicio.<\/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        \\\/\\\/ Asumiendo que la autenticaci\u00f3n ha pasado, ejecuta el manejador original\n        next.ServeHTTP(w, r)\n    })\n}<\/code><\/pre>\n<p>\nExisten enrutadores de terceros, como chi, que permiten ampliar la funcionalidad de la intermediaci\u00f3n.<\/p>\n<h3>Trabajo con archivos est\u00e1ticos<\/h3>\n<p>\nLa biblioteca est\u00e1ndar de Go incluye capacidades para trabajar con contenido est\u00e1tico, incluyendo im\u00e1genes, as\u00ed como archivos JavaScript y CSS. Se puede acceder a ellos a trav\u00e9s de la funci\u00f3n http.FileServer. Esta devuelve un manejador que distribuye archivos desde un directorio espec\u00edfico.<\/p>\n<pre><code class=\"go\">func NewRouter() http.Handler {\n    router := chi.NewRouter()\n    r.Get(\"\/{name}\", HelloName)\n \n\/\/ Configuraci\u00f3n para servir archivos est\u00e1ticos\nstaticPath, _ := filepath.Abs(\"..\\\/..\\\/static\\\/\\\")\nfs := http.FileServer(http.Dir(staticPath))\n    router.Handle(\"\/*\", fs)\n    \n    return r<\/code><\/pre>\n<p>\nEs importante recordar que http.Dir muestra el contenido del directorio si no hay un archivo principal index.html en \u00e9l. En este caso, para prevenir la exposici\u00f3n del directorio, se debe usar el paquete <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/jordan-wright\/unindexed\"><code>no indexado<\/code><\/a><\/noindex>.<\/p>\n<h3>Cierre correcto<\/h3>\n<p>\nEn Go, existe una funci\u00f3n para el cierre adecuado del servidor HTTP. Esto se puede hacer utilizando el m\u00e9todo Shutdown(). El servidor se ejecuta en una goroutine, y luego se escucha un canal para recibir la se\u00f1al de interrupci\u00f3n. Una vez recibida la se\u00f1al, el servidor se apaga, pero no inmediatamente, sino despu\u00e9s de unos segundos.<\/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\/\/ Esperar a una interrupci\u00f3n\nc := make(chan os.Signal, 1)\nsignal.Notify(c, os.Interrupt)\n&lt;-c\n \n\/\/ Intentar un cierre elegante\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nsrv.Shutdown(ctx)<\/code><\/pre>\n<p><\/p>\n<h3>En conclusi\u00f3n<\/h3>\n<p>\nGo es un lenguaje poderoso con una biblioteca est\u00e1ndar pr\u00e1cticamente universal. Sus capacidades predeterminadas son bastante amplias, y se pueden mejorar mediante interfaces, lo que permite desarrollar servidores HTTP realmente confiables.<\/p>\n<blockquote><p><b>Skillbox recomienda:<\/b><\/p>\n<ul>\n<li>Curso pr\u00e1ctico de dos a\u00f1os <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/\">\u00abSoy Desarrollador Web PRO\u00bb<\/a><\/noindex>.<\/li>\n<li>Curso en l\u00ednea educativo <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/java\/\">\u00abProfesi\u00f3n Desarrollador Java\u00bb<\/a><\/noindex>.<\/li>\n<li>Curso pr\u00e1ctico de un a\u00f1o <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/\">\u00abDesarrollador PHP desde 0 hasta PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Fuente: <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 - 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\/es\/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\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47 Desarrollo de servidores web en Golang \u2014 de lo simple a lo complejo | ProHoster","description":"Hace cinco a\u00f1os comenc\u00e9.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/news\/razrabotka-veb-serverov-na-golang-ot-prostogo-k-slozhnomu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/30782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=30782"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/30782\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/22767"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=30782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=30782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=30782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}