Aqui el codigo actualizado
main.go
package main
func main() {
server := NewServer(":3000")
//uso de la funcion handle con el path "/" y el handler
server.Handle("/", HandleRoot)
server.Handle("/api", HandleHome)
server.Listen()
}
server.go
//el archivo main va a poder leer todo lo que este en el archivo server
package main
import (
"net/http"
)
type Server struct{
//puerto del servidor para escuchar las conexiones
port string
//se agrega el atributo router que es un apuntador al struct Router de router.go
router *Router
}
//Funcion tipo global para ser leida en otros archivos
//Sirve para instanciar el servidor y que sea capaz de escuchar las conexiones
//recive el puerto que tiene que estar escuchando y devuelve el servidor como tal
func NewServer(port string) *Server {
return &Server{
port: port,
//router instanciado
router: NewRouter(),
//con esto el servidor ya es capaz de instanciar el router y de tenerlo como propiedad
}
}
//Handle es el nombre de la ruta por ejemplo "/api" asignado a un handler especifico
func (s *Server) Handle(path string, handler http.HandlerFunc){
//Asociacion del handler con la ruta, es decir, el mapa con la llave path asignado al handler
s.router.rules[path] = handler
//asi el servidor es capaz de agregar la ruta especifica a un handler especifico
}
//Funcion tipo receiver, del struct Server, devuelve un error en caso de que haya problemas al conectar
func (s *Server) Listen() error{
//el router va a ser el encargado de tomar las urls y procesarlas como se debe, crea el entry-point
// los parametros son: el slash que es el punto de entrada, y el handler es el router recien creado
http.Handle("/", s.router)
//con la funcion listenanserve() del paquete http nos ayuda a escuchar todas las peticiones
//colocas el puerto como primer parametro, el segundo es un handler
//pero nosotros haremos nuestros handlers por eso se coloca nil
err := http.ListenAndServe(s.port, nil)
if err != nil {
return err
}
//si la ejecucion salio bien, retorna un valor nil
return nil
}
router.go
package main
import(
"net/http"
)
//Struct router para hacer request en el servidor
type Router struct{
//Reglas para definir de que rutas pasan a que handler, mapa que pasa de strings a handler
//mapa que tenga como llaves strings y que mapee a HandlerFunc
rules map[string]http.HandlerFunc
}
//forma de instanciar el router, similar al NewServer() del archivo servidor.go
func NewRouter() *Router {
return &Router{
//a diferencia del servidor, aqui el router debe empezar en un estado vacio, creamos un mapa vacio
rules: make(map[string]http.HandlerFunc),
}
}
//funcion que recibe el path que es un mapa y que devuelve dos valores:
//valor que devuelve y el valor booleano para saber si existe o no la llave dentro del mapa
func (r *Router) FindHandler(path string) (http.HandlerFunc, bool){
//asignacion de el valor en el mapa de reglas a las variables handler y exist
handler, exist := r.rules[path]
return handler, exist
}
//Metodo ServeHTTP de router para poder implementar en el handler el atributo s.router en server.go
//parametros: el primero es el escritor, el segundo es el request en donde viene la informacion
//no olvidar colocar ServeHTTP con letras mayusculas
func (r *Router) ServeHTTP(w http.ResponseWriter, request *http.Request) {
//manejo del mensaje de manera dinamica
//r es la referencia al router y usar la funcion FindHandler
//el FindHandler compara el request con el mapa de reglas para saber si existe o no.
//los valores son asignados a las variables 'handler' y 'exist'
handler, exist := r.FindHandler(request.URL.Path)
//Evaluacion del booleano del handler para saber si existe o no, error 404
if !exist{
//WriteHeader es para indicar el status del request
w.WriteHeader(http.StatusNotFound)
//el return nos ayuda a romper la funcion si esto no existe el handler
return
}
//handler para enviar objeto w y request
handler(w, request)
}
handlers.go
package main
import (
"net/http"
"fmt"
)
// Handler para manejar la ruta principal
//Parametros: escritor w del tipo http.ResponseWriter y objeto request
func HandleRoot(w http.ResponseWriter, r *http.Request) {
//Impresion en el navegador
//parametros: escritor-objeto encargado de responder al cliente
//y mensaje escrito a travez del escritor
fmt.Fprintf(w, "Hello World from handlers")
}
func HandleHome(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "This is the API Endpoint")
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.