CursosEmpresasBlogLiveConfPrecios

Modelo Posts

Clase 17 de 26 • Curso de Go Avanzado: REST y WebSockets

Contenido del curso

Introducción

  • 1
    Introducción al curso

    Introducción al curso

    02:27 min
  • 2
    ¿Qué estaremos construyendo?

    ¿Qué estaremos construyendo?

    04:51 min
  • 3
    HTTP y REST

    HTTP y REST

    06:34 min
  • 4
    CRUD

    CRUD

    05:58 min

REST

  • 5
    Inicialización de módulo e instalación de dependencias

    Inicialización de módulo e instalación de dependencias

    02:43 min
  • 6
    Struct Server

    Struct Server

    12:02 min
  • 7
    Nuestro primer endpoint

    Nuestro primer endpoint

    17:34 min
  • 8
    Definiendo el modelo de usuarios

    Definiendo el modelo de usuarios

    03:03 min
  • 9
    Patrón repository

    Patrón repository

    08:39 min
  • 10
    Registro de usuarios

    Registro de usuarios

    17:05 min
  • 11
    Implementando el registro

    Implementando el registro

    20:32 min
  • 12
    Probando los registros

    Probando los registros

    09:29 min
  • 13
    Autenticación de usuarios

    Autenticación de usuarios

    20:51 min
  • 14
    Probando el login

    Probando el login

    05:04 min
  • 15
    Middleware de validación de autenticación

    Middleware de validación de autenticación

    11:45 min
  • 16
    Implementando el middleware

    Implementando el middleware

    10:19 min
  • 17
    Modelo Posts

    Modelo Posts

    Viendo ahora
  • 18
    CRUD para Posts

    CRUD para Posts

    19:46 min
  • 19
    Paginación para Posts

    Paginación para Posts

    13:35 min

WebSockets

  • 20
    Websockets

    Websockets

    06:40 min
  • 21
    Upgrader y Endpoint para Websocket

    Upgrader y Endpoint para Websocket

    11:23 min
  • 22
    Struct de Hub para conexiones

    Struct de Hub para conexiones

    07:55 min
  • 23
    Implementando el Broadcast

    Implementando el Broadcast

    11:10 min

Cierre

  • 24
    Ejemplo de implementación frontend

    Ejemplo de implementación frontend

    14:54 min
  • 25
    Docker file para producción

    Docker file para producción

    11:44 min
  • 26
    Siguientes pasos y mejoras

    Siguientes pasos y mejoras

    01:39 min
Tomar examen

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

      Comentarios

      Andrés Felipe Perdomo Alvarado

      Andrés Felipe Perdomo Alvarado

      student•
      hace 9 meses
        José Antonio De La Paz Fonseca

        José Antonio De La Paz Fonseca

        student•
        hace 8 meses
      Felipe Hernández

      Felipe Hernández

      student•
      hace 3 años
      Carlos Eduardo Magallon Zepeda

      Carlos Eduardo Magallon Zepeda

      student•
      hace 4 años
      Carlos Eduardo Magallon Zepeda

      Carlos Eduardo Magallon Zepeda

      student•
      hace 4 años
      Carlos Arturo Pimentel

      Carlos Arturo Pimentel

      student•
      hace 4 años
        José Antonio De La Paz Fonseca

        José Antonio De La Paz Fonseca

        student•
        hace 8 meses
      Oscar Pinochet

      Oscar Pinochet

      student•
      hace 3 años

      Hola, yo resolví el tema de extraer el usuario con base en el func CreatePostHandler(s server.Server) http.HandlerFunc {    return func(w http.ResponseWriter, r *http.Request) {        var req CreatePostRequest        if err := json.NewDecoder(r.Body).Decode(&req); err != nil {            http.Error(w, "Invalid request body", http.StatusBadRequest)            return        }         user := services.UserServiceInstance.GetUserFromToken(r, s, w)         post := models.Post{            Title:   req.Title,            Content: req.Content,            UserID:  user.Id,        }         err := repository.CreatePost(r.Context(), &post)        if err != nil {            http.Error(w, "Error creating post: "+err.Error(), http.StatusInternalServerError)            return        }         w.Header().Set("Content-Type", "application/json")        w.WriteHeader(http.StatusCreated)        json.NewEncoder(w).Encode(post)    }}usuarioId del Token, de la siguiente forma:

      post_handler.go

      func CreatePostHandler(s server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req CreatePostRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } user := services.UserServiceInstance.GetUserFromToken(r, s, w) ... } }

      user_service.go

      var ( ErrUserNotFound = errors.New("user not found") ) // UserService contiene la lógica de negocio relacionada con usuarios type UserService struct{} // GetUserFromToken combina las utilidades de JWT con la lógica de negocio // para obtener un usuario completo desde un token en la request func (us *UserService) GetUserFromToken(r *http.Request, s server.Server, w http.ResponseWriter) *models.User { // Usar utilidad para extraer token tokenString, err := utils.ExtractTokenFromRequest(r) if err != nil { http.Error(w, "Authorization header is required", http.StatusUnauthorized) return nil } // Usar utilidad para validar token y obtener claims claims, err := utils.ParseAndValidateToken(tokenString, s.Config().JWTSecret) if err != nil { http.Error(w, "Invalid token: "+err.Error(), http.StatusUnauthorized) return nil } // Lógica de negocio: obtener usuario de la base de datos user, err := repository.GetUserById(context.Background(), claims.UserId) if err != nil { http.Error(w, "User not found: "+err.Error(), http.StatusNotFound) return nil } return user } // Instancia global del servicio (patrón Singleton simple) var UserServiceInstance = &UserService{} ```**auth\_util.go** ```js var ( ErrMissingAuthHeader = errors.New("missing Authorization header") ErrInvalidToken = errors.New("invalid token") ErrInvalidClaims = errors.New("invalid token claims") ) // ExtractTokenFromRequest extrae el token JWT del header Authorization de la request // Esta es una función utilitaria pura que solo se encarga de la extracción func ExtractTokenFromRequest(r *http.Request) (string, error) { tokenString := strings.TrimSpace(r.Header.Get("Authorization")) if tokenString == "" { return "", ErrMissingAuthHeader } return tokenString, nil } // ParseAndValidateToken parsea y valida un token JWT, devolviendo los claims // Esta función es pura y no tiene efectos secundarios func ParseAndValidateToken(tokenString string, jwtSecret string) (*models.AppClaims, error) { token, err := jwt.ParseWithClaims(tokenString, &models.AppClaims{}, func(token *jwt.Token) (any, error) { return []byte(jwtSecret), nil }) if err != nil || !token.Valid { return nil, ErrInvalidToken } if claims, ok := token.Claims.(*models.AppClaims); ok && token.Valid { return claims, nil } return nil, ErrInvalidClaims }

      Excelente, pensé que no había nadie en éstos cursos por éstos días, conectemos en linkedin:

      Debido a que los usuarios normalmente tienen asociadas operaciones de base de datos exclusivas (autenticación, chequeo y hashing de passwords, chequeo de permisos, etc.), preferiría no convertir el UserRepository dentro de una interfaz regular, sino seguir el patrón que utiliza Spring con el CrudRepository y crear uno aparte con las operaciones CRUD generalizadas.

      El código del Handler

      type InsertPostRequest struct { PostContent string `json:"post_content"` } type PostResponse struct { Id string `json:"id"` PostContent string `json:"post_content"` } func InsertPostHandler(s server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { tokenString := strings.TrimSpace(r.Header.Get("Authorization")) token, err := jwt.ParseWithClaims(tokenString, &models.AppClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(s.Config().JWTSecret), nil }) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } if claims, ok := token.Claims.(*models.AppClaims); ok && token.Valid { var postRequest = InsertPostRequest{} if err := json.NewDecoder(r.Body).Decode(&postRequest); err != nil { return } id, err := ksuid.NewRandom() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } post := models.Post{ Id: id.String(), PostContent: postRequest.PostContent, // Remember to use claims.UserId, not claims.Id UserId: claims.UserId, } err = repository.InsertPost(r.Context(), &post) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(PostResponse{Id: post.Id, PostContent: post.PostContent}) } else { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }

      Del Struct

      package models import "time" type Post struct { Id string `json:"id"` PostContent string `json:"post_content"` CreatedAt time.Time `json:"created_at"` UserId string `json:"user_id"` }

      Para el caso que se necesite extender la funcionalidad del CRUD, para ciertos modelos solamente, se podría crear varios repositorios adicionales, así sea que cada repositorio tuviese sólo un método ?

      Excelente que estés aprendiendo go, pensé que era el único en éstos cursos por éstos días, hagamos conexión por linkedin:

      Ojo que en la linea donde esta

      json.NewDecoder(r.body).Decode(&postRequest)

      no hay validación de que el json sea valido, ya que el metodo decode no hace esa validación. una forma de tener esa validación es con json.Unmarshal, ya que va a caer en error si es que hay un json invalido.

      body, err := io.ReadAll(r.Body) if err != nil { fmt.Println(err) http.Error(w, err.Error(), http.StatusBadRequest) return } defer func() { err = r.Body.Close() if err != nil { fmt.Println(err) } }() err = json.Unmarshal(body, &postRequest) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return }

      o también se puede evaluar si es que hay algo mas que no debería estar. con

      jsonDecoder := json.NewDecoder(r.Body) if jsonDecoder.More() { http.Error(w, "invalid json", http.StatusBadRequest) return } err := jsonDecoder.Decode(&postRequest) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return }

      preferentemente se usa la primera opción ya que con eso nos aseguramos de que el cuerpo de la llamada es leído y luego es cerrado