03. Go web: ¿cómo servir páginas con Golang?

Publicado por

En la primera entrada aprendimos a crear páginas estilo wiki con Golang, mientras que en la segunda entrada creamos un pequeño servidor web. En esta ocasión vamos a combinar lo visto en ambas entradas para servir páginas wiki.

Servidor de páginas wiki

Comenzamos creando un archivo con extensión .go que será el servidor (eres libre de nombrarlo como quieras, en mi caso le llamaré ‘servidor_wikis’. Lo abrimos e importamos los 3 paquetes que vamos a necesitar:

import (
  "fmt"
  "io/ioutil"
  "net/http"
)

Si no recuerdas por qué importamos alguno de esos paquetes, te recomiendo que revises las entradas anteriores para mayor información (io/ioutil aquí, net/http aquí).

En seguida vamos a crear la función manejadora (handler) que se encargará de mostrar las páginas wiki.

func manejadorMostrarPagina(w http.ResponseWriter, r *http.Request){
  titulo := r.URL.Path
  pagina, _ := cargarPagina(titulo)
  fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>",
    pagina.Titulo[len("/view/"):], pagina.Cuerpo)
}

Con r.URL.Path extraemos la ruta y el título de la página desde la URL que pide el cliente. Yo escogí la ruta «/view” para mis páginas, tú puedes usar cualquier otra que desees.

En seguida, la función carga la página, le agrega etiquetas HTML para dar formato y, finalmente, la guarda en w(la respuesta para el cliente). En mi caso creo un slice con el título de la página porque, de otro modo, incluiría el prefijo “/view/” en referencia a la ruta de acceso.

Para hacer el llamado a este manejador desde la función principal (main()) inicializamos el paquete http para que escuche peticiones hechas a la ruta “/view/” y las sirva con manejadorMostrarPagina(). El puerto que escuchará nuestro servidor será el 8080:

func main(){
  http.HandleFunc("/view/", manejadorMostrarPagina)
  http.ListenAndServe(":8080", nil)
}

Para compilar y ejecutar desde terminal de Linux:

go build servidor_wikis.go
./servidor_wikis

El siguiente es el código completo del servidor junto con las wiki:

package main
import (
  "fmt"
  "io/ioutil"
  "net/http"
)

type Pagina struct{
  Titulo string
  Cuerpo []byte
}

func main(){
  //Creamos y guardamos una página para que el cliente la pida
  pag1 := &Pagina{ Titulo: "Ejemplo", Cuerpo:[]byte(
    "¡Hola personita! Este es el cuerpo de tu página.") }

  pag1.guardar()

  http.HandleFunc("/view/", manejadorMostrarPagina)
  fmt.Println("El servidor se encuentra en ejecución");
  http.ListenAndServe(":8080", nil)
}

//Manejador de peticiones
func manejadorMostrarPagina(w http.ResponseWriter, r *http.Request){
  titulo := r.URL.Path
  pagina, _ := cargarPagina(titulo)
  fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>",
    pagina.Titulo[len("/view/"):], pagina.Cuerpo)

  fmt.Println("¡Página servida!")
}

//Método para guardar página
func ( p* Pagina ) guardar() error {
  nombre := p.Titulo + ".txt"
  return ioutil.WriteFile( "./view/" + nombre, p.Cuerpo, 0600)
}

//Método para cargar página
func cargarPagina( titulo string ) (*Pagina, error) {
  nombre_archivo := titulo + ".txt"
  fmt.Println("El cliente ha pedido:" + nombre_archivo)
  cuerpo, err := ioutil.ReadFile( "." + nombre_archivo )

  if err != nil {
    return nil, err
  }
  return &Pagina{Titulo: titulo, Cuerpo: cuerpo}, nil
}

Nota importante: recuerda que es necesario crear una carpeta con el nombre ‘view’ para que este ejemplo funcione. Si tu usaste otra ruta, será indispensable que modifiques el código además de crear las respectivas carpetas.

Para mostrar nuestra página, accedemos al siguiente enlace (ten cuidado de ingresar la URL tal como aparece a continuación):

http://localhost:8080/view/Ejemplo

Finalizando…

Espero que te haya servido lo que estudiamos en esta entrada. A pesar de ser bastante sencillo crear un servidor, te recomiendo que practiques un poco para dominarlo. En la siguiente entrada te mostraré cómo crear un editor simple para tus páginas wiki.

11 comments

  1. lo que no entiendo bien es si el archivo servidor_wikis.go va dentro de la carpeta view, o si tengo que ubicarlo fuera de ella pero a su mismo nivel. además, no veo la página que sirve. no sé si crea temporalmente o hay que crearla manualmente. esa son mis dudas. gracias

    1. Hola, Aquila, perdón por no haber respondido antes. El servidor va en la raíz del servidor. El código de ejemplo crea una página de ejemplo para probar el funcionamiento.

  2. quisiera saber si servir páginas con golang es mejor que hacerlo con nodejs. al parecer este último también tiene sus ventajas. gracias

    1. Saludos, se que ha pasado tiempo , pero recordaras como lo hiciste? tengo el mismo problema ,he revisado todo el codigo y no veo el error
      gracias

      1. Hola, una respuesta 404 significa que estas intentando acceder a un archivo que no existe. Por favor intenta confirmar que tu código esta ejecutándose sin problemas y que estas utilizando la dirección correcta sin errores como «veiw» en lugar de «view». Después de confirmar eso, ¿aun tienes el mismo problemas?

        Gracias por leernos.

    1. Hola, gracias por leernos. El segundo parametro es enviado para especificar el «handler», o el controlador en español. Super resumido, te permite especificar lo que hará tu aplicación con todas las peticiones como por ejemplo los 404. Al usar nil estás usando el por defecto DefaultServeMux.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *