Os dejo aquí el skeleton para empezar nuevos proyectos usando express: github.com/AlbertHernandez/express-typescript-service-skeleton Y también el skeleton para crear aplicaciones siguiendo la arquitectura hexagonal: github.com/AlbertHernandez/hexagonal-architecture-typescript-service-skeleton
@Bleibruk
Жыл бұрын
Llevaba tiempo viendo video al respecto, incluso videos prácticos... pero este fue el más simplificado y donde terminé entendiendo y encajando todo lo que ya había leído
@AlbertHernandez
Жыл бұрын
Me alegro que lo hayas entendido :)
@Ruben_PX
Жыл бұрын
Opino lo mismo
@gonzaloramirez3261
7 ай бұрын
Genio! no encontré otro video que lo explique tan bien como lo haces vos, vengo de hacer backend con Java y estas explicaciones me vienen muy bien 😄
@AlbertHernandez
7 ай бұрын
Muchas gracias 😁😁
@geekhadev
Жыл бұрын
Sería genial una clase de como implementar arquitectura hexagonal con los videos que tienes de nestjs
@AlbertHernandez
Жыл бұрын
Sii, es uno que estoy preparando y que espero traerlo pronto al canal :)
@iv4n89
Жыл бұрын
Gracias! Al fin encuentro a alguien que lo explica sin irse por las ramas :D
@miguelr.miller6237
5 ай бұрын
Genial vídeo! Hace poco descubrí tu canal por un vídeo sobre NestJs, y pude ver que tienes más material! Tengo 2 consultas: 1. Si pudieras realizar un vídeo sobre vertical slicing + arquitectura hexagonal, y 2. otro sobre cómo aplicarlo también en el frontend. Saludos!
@AlbertHernandez
5 ай бұрын
Muchas gracias! Respecto al primero si claro, ese lo tengo super apuntado hehe tambien quiero ver si traigo contenido de hexagonal pero aplicado a NestJS. Respecto al punto 2, de frontend no soy muy experto y me temo no explicar tan bien las cosas, pero justo el equipo de CodelyTV tiene un curso de hexagonal en frontend que al igual te sirve, yo no lo he hecho pero tiene muy buena pinta: codely.com/cursos/arquitectura-hexagonal-en-frontend_5159
@miguelr.miller6237
3 ай бұрын
@@AlbertHernandez Una consulta, si tuviera DTO's como createUser o updateUser, donde deberían colocarse? En el domain?
@victorballarin4218
5 ай бұрын
Acabo de descubrirte, felicidades gran explicación y práctica, gracias y ánimo con el contenido de calidad!
@AlbertHernandez
5 ай бұрын
Muchas gracias!! Espero seguir trayendo más contenido de calidad 😁
@juancarlosuribebedoya7761
15 күн бұрын
Muchas gracias por este video!
@marcosbarranquero8289
Жыл бұрын
Ta mu bien, gracias por el vídeo!
@LuisVB07
Жыл бұрын
Excelente capacitación Albert ..!! 👏
@hansalamo9850
Жыл бұрын
excelente video, me ayudo mucho, saludos desde Venezuela
@davidllanes1019
3 ай бұрын
Nunca había visto una implementación de esta arquitectura. Me gustó mucho el video :). ¿Cuál es la diferencia con el MVC?
@AlbertHernandez
3 ай бұрын
La diferencia principal es que en la MVC es en el modelo donde tenemos toda la logica de datos e incluso tendria la logica de obtener su informacion y de guardarlas Una arquitectura como la hexagonal, que esta basada en la clean architecture, se centra en que la logica de nuestra aplicacion no este acoplada a los detalles de infra como puede ser esa capa de persistencia de datos
@dmartinezbello
4 ай бұрын
Muy agredecido por tu contenido. Quiera saber si todavía a estás creando contenido.? Quisiera saber si puedes hacer algo para explicar todos estos conceptos de Arquitectura Hexagonal con buses de eventos como por ejemplo un carrito de compra que cuando se ejecute un pago se actualice la orden de compra y que además se registre el pago. Esto creo que sería de gran ayuda para completar tu set de videos… muchas gracias de antemano
@AlbertHernandez
4 ай бұрын
Gracias ^^ Pues ahora mismo tengo el canal parado porque hace poco cambié de trabajo y no estoy teniendo mucho tiempo pero la idea es seguir creando más contenido una vez ya me termine de habituar Respecto a los buses si claro, es algo que podemos ir viendo, justo en el nuevo trabajo hacemos uso intenso de los buses y patrones como CQRS por lo que espero poder traer contenido de todo lo que vaya aprendiendo :D Un saludo!
@dmartinezbello
4 ай бұрын
@@AlbertHernandez mis mejores deseos para ti en tu nuevo trabajo… se nota lo bueno que eres… éxitos
@AlbertHernandez
4 ай бұрын
Muchas gracias 😁
@sebaespinosa
Жыл бұрын
Gracias por el video, tengo una duda, he escuchado mucho hablar en esta arquitectura también de "puertos" y "adaptadores"... es el equivalente a las capas de "infraestructura" y "aplicación"???
@AlbertHernandez
Жыл бұрын
Hola! Sí, esta arquitectura también se le llama así: los puertos serían el dominio y los adapters la infraestructura, que sería donde implementamos las interfaces del dominio
@sebagtorres
10 ай бұрын
Excelente explicación!!
@AlbertHernandez
10 ай бұрын
Gracias!
@itmarck
Жыл бұрын
Muy bueno, estaría bueno una idea de cómo podría escalar esto a aplicaciones muchos más grandes con muchas entidades. PD: Recordar que hay veces donde el send email no necesita un await, sobretodo cuando se envían en segundo plano, para que sea un stopper en la petición
@AlbertHernandez
Жыл бұрын
Sí, la idea principal con este video era introducir la arquitectura, pero tengo intención de sacar un cursillo así más completo donde se vea cómo crear una app desde cero y un poco más grande (pero ya sabes, el tiempo es un poco limitado y entre el trabajo, vida personal y demás no me está dando la vida para hacer todo lo que me gustaría, pero bueno, espero poder ir sacando cosillas que os vaya interesando) Por cierto, me sumo a lo de enviar los emails en segundo plano, pero subo la apuesta :) Metería una gestión de colas, por ejemplo, con Redis usando Bull para hacer todo este trabajo en background y así poder tener temas de retries, que si se para el servidor no pasa nada y demás. Creo que me has dado la idea de hacer un video de cómo hacer todo esto hehe
@itmarck
Жыл бұрын
@@AlbertHernandez jaja si cierto, dejarlo ahí simplemente en segundo plano solo no sería suficiente. Dale con todo
@gposoft
Жыл бұрын
Excelente gracias !
@hernaldocastro8944
Жыл бұрын
Estimado, gracias por tu aporte. Ame tu editor y config de este. Me compartes su nombre y extensiones por favor
@AlbertHernandez
Жыл бұрын
Buenas! De editor uso IntelliJ Idea. En cuanto a las extensiones, no suelo utilizar muchas, ya que este IDE ya viene con mucha funcionalidad por defecto. Sin embargo, hay algunas que recomendaría como extras: - .env files support (para tener soporte para los archivos .env) - Monokai Pro Theme (para tener un tema bonito en el IDE) - Atom Material Icons (para los iconos de los archivos y carpetas) - String Manipulation (para cambiar rápidamente entre snake_case y camelCase, entre otros) Lo más probable es que en el futuro haga algún video mostrando cómo lo tengo configurado todo. ¡Espero que os guste! :)
@rbjmalca2
7 ай бұрын
Se ve muy tedioso, tendría que acostumbrarme practicando y que no se me pase alguna interacción entre capas como dices. Bueno con respecto a mi duda es si puedo usar librería de terceros a nivel de aplicacion, digamos moment? O tendría que hacerle su interfaz donde inyecte a moment ?
@AlbertHernandez
7 ай бұрын
Si, es un poco tedioo eso no lo niego, pero lo bueno es que conseguimos estar bastante desacoplados de terceros mediante el uso de interfaces y esas capas de dominio / infra. Respecto al uso de librerias como moment, si hablamos desde un punto de vista purista, no deberia ir en el dominio y deberiamos crear una interfaz. Sin embargo, muchas veces se paga el trade-off y se asume que esta libreria como puede ser moment, lodash, un validator de uuids son parte de nuestro dominio, ya que el coste de crear una interfaz que encima va a estar super acoplada a una libreria es mucho mayor que el hecho de meter esta libreria en nuestro dominio. Al final esto es algo que debemos de evaluar si estamos dispuestos a pagar el precio o no
@robertcaraballo2145
Жыл бұрын
Hola.!, tu video me ayudo muchísimo a entender esto y más para un proyecto que empezaré a refactorizar por servicios. Una duda: ¿La infraestructura puede hablarse con otra infraestructura? Ejemplo, si tengo “usuarios” y “operaciones”, quiero tener eso por separado, pero tienen relación entre sí. Estaba pensando que se podría igual con las inyecciones de dependencias a un servicio y exponerlo a distintas entidades de mi app, pero no estoy seguro.
@AlbertHernandez
Жыл бұрын
Hola! La infraestructura puede hablar con toda la infraestructura que desees, la regla en sí solo dice que el dominio o la aplicación no pueden hablar con la infra. Ahora, un consejo que te doy, que es como suelo hacerlo, es el siguiente: si la infraestructura que estás usando no está relacionada con su propio contexto, suelo preferir inyectar la interfaz de dominio, ya que esto me permitirá cambiar en el futuro esa infraestructura sin realizar muchos cambios. Te pongo un ejemplo para que esto se vea más claro. Si tengo un repositorio de usuarios, por ejemplo, con mongo, no veo problema en que esa parte de la infraestructura sepa cosas sobre la conexión con mongo, los esquemas, etc., ya que al final está hablando con otra infraestructura, pero de su propio contexto, en este caso mongo. Sin embargo, si ese repositorio necesita, por ejemplo, un logger u otras cosas que no estén tan relacionadas, lo mejor sería que utilices la abstracción que tienes en el dominio, de manera que tu repositorio no sepa cómo estás implementando el logger, ya que si en el futuro quieres cambiar de logger, lo ideal sería que solo lo cambiaras en un punto y no tuvieras que modificar cosas de la base de datos porque no están relacionadas. Al final, no hay ninguna regla de oro y muchas veces depende del contexto. Lo que te recomiendo más es que pienses si te interesa que esto esté totalmente aislado para tener esos dos módulos de infraestructura independientes, o si están muy relacionados y no te merece la pena hacerlo. Espero que te haya ayudado, un saludo!
@robertcaraballo2145
Жыл бұрын
@@AlbertHernandez Entendido.! , Si superbién explicado. Ya ando haciendo prototipos para el nuevo servicio basado en eso y aplicando las recomendaciones SOLID. Tus videos me están ayudando mucho.
@AlbertHernandez
Жыл бұрын
Me alegro!
@jhosagidpirelapineda7808
10 ай бұрын
Excellente!
@AlbertHernandez
10 ай бұрын
Gracias! 😁
@rodrigovazquez259
Жыл бұрын
Hola, en donde irian los archivos .EJS o .HTML, ya que en esta arquitectura no tengo la carpeta views
@AlbertHernandez
Жыл бұрын
Hola! Pues las views las pondria en la infraestructura ya que al final son representaciones o respuestas que se les entregan a los clientes / usuarios
@EliasAlmarza
8 ай бұрын
¿me recomiendas esto para crear microservicios complejos? utilizando un patrón apigateway para centralizar estos.
@AlbertHernandez
8 ай бұрын
La arquitectura hexagonal y con vertical slicing viene muy bien para diseñar servicios más medianos y grandes, por lo que te puede ir bien si. Lo que si te preguntaría es si de verdad necesitas microservicios para solucionar el problema al que te enfrentas o si con un monolito bien diseño puedes ir comenzando y poco a poco ir evolucionando
@abelmurua6980
Жыл бұрын
excelente
@NeryCano
2 ай бұрын
me encanta como explicas pero tu editor no muestra en que carpeta estas y se vuelve muy confuso
@AlbertHernandez
2 ай бұрын
Gracias! Si, ha sido algo que me habeis comentado varios, ya en nuevos videos he puesto el path del fichero de donde estoy para que asi quede esto mas claro, gracias por el feedback, un saludo 😁
@JoShMiQueL
Жыл бұрын
He visto el video 20 veces y no me entero 😭, no soy capaz de entenderlo 🫠
@AlbertHernandez
Жыл бұрын
Vaya lo lamento, te aconsejo que veas varios videos de este tipo de arquitectura y articulos, habra un punto donde hagas "clip" y todo cobre sentido, a todos nos pasa, si tienes alguna duda en concreto sientete libre de preguntar :)
@moviedomof
Жыл бұрын
raro que no usaste awilix para IoC dadoi que en otros videos alcaras que es el tu preferido y (desde 5 años de uso) Estaria bueno un video completo pseudo real con agregados y contextos de dominio dode realmente se vea la aplicacion de la ARQ .
@AlbertHernandez
Жыл бұрын
Si, en efecto, Awilix es de mis IoC preferidos. Para explicar la hexagonal he preferido no introducir contenedores ya que no era el propósito principal de este video (para eso ya esta el propio de Awilix y sino se quedaba muy largo). Me apunto lo de un video donde se vea algo mas completo donde se junten distintas técnicas
@moviedomof
Жыл бұрын
@@AlbertHernandez claro y ahi es donde se complica con babel en el dis (no toma los @router) si funciona ok en dev mode sobre ts. tuve q pasar todo a a inversify
@AlbertHernandez
Жыл бұрын
Creo que esta mas relacionado a como se inicia la app que otra cosa, Awilix con Hexagonal es totalmente viable (tengo apps en produccion con esto), me resulta raro que hayas tenido que pasar a inversify. Tienes algun proyecto en github con el que pueda reproducir ese error que me comentas? Por si le puedo dar un vistazo y asi te comento lo que encuentre
@moviedomof
Жыл бұрын
@@AlbertHernandez si si tengo un ecosistema demo de microservicios que estoy haciendo para unas capacitaciones te lo puedo compartir dime donde..Desde ya gracias
@AlbertHernandez
Жыл бұрын
Subelo a GitHub mismo y dame acceso para poder acceder, tambien estaria bien si me facilitas un correo electronico para poder ir hablando, por aqui es un poco engorroso :)
@Federrocky
11 ай бұрын
Excelente video, uno de los pocos que muestra un ejemplo real de la estructura de carpetas que a menudo se pasa por alto. Lo único que no me convence es cuando mencionas dos ventajas de la arquitectura hexagonal y hablas de tener separada la implementación de acceso a datos y que cumple con los principios SOLID. Si bien esto es cierto, una arquitectura 'tradicional' por capas usando el patrón repositorio y el patrón strategy ya proporciona los mismos beneficios.
@AlbertHernandez
11 ай бұрын
Gracias! Sí, correcto. Con un patrón repository conseguimos lo mismo. Es más, la arquitectura hexagonal se suele usar mucho con dicho patrón, ya que el repository, digamos, sería la interfaz de dominio y luego la implementación estaría en la capa de infraestructura. La diferencia, según veo, está en dónde situamos dichos archivos y ya no solo para el acceso a datos sino luego otros módulos que podamos tener pueden como pueden ser clientes de correo, sistemas de mensajería...
@NeryCano
2 ай бұрын
el .bind no esta de mas en las rutas?
@AlbertHernandez
2 ай бұрын
Sin el .bind perderiamos el contexto del this, por lo que luego daria error al acceder desde el controller a el. Una manera de solucionar esto es mediante el bind, otra puede ser mediante arrow functions pero en este caso he optado por la primera
@TheGreyOlorin
Жыл бұрын
Molaría mucho ver un vídeo sobre un proyecto sencillo en el que se usaran varios modelos para poder ver en práctica la ganancia que se obtiene en escalabilidad usando este tipo de arquitectura pero desde luego que es muy buena base para empezar a trastear, sólo digo que por tu forma de explicar, estaría genial porque lo haces muy bien.
@AlbertHernandez
Жыл бұрын
Hola! Sí, ya llevo tiempo pensando en crear algún curso un poco más completo donde se vean cómo podemos unir todas las piezas que estamos viendo en los videos y en un contexto un poco más complejo. Un saludo!
@matiassantiago4205
Жыл бұрын
@@AlbertHernandez es momento!
@arieldominguez9034
Жыл бұрын
@@AlbertHernandez Me sumo al curso...
@SkinDeath887
3 ай бұрын
Hola buen vídeo. Recién comienzo con esto de la programación y las arquitecturas limpias y ojala puedan ayudarme. /proyecto │ ├── /src │ ├── /Cursos │ │ ├── /Domain │ │ ├── /Application │ │ └── /Infrastructure │ │ │ ├── /Estudiantes │ │ ├── /Domain │ │ ├── /Application │ │ └── /Infrastructure Actualmente tengo el crud de cursos y ahora estoy creando el crud de estudiantes, pero la regla de negocio dice que un estudiante puede tener 1 o muchos cursos por ende en la clase estudiante debería tener un array de cursos. Es aquí donde me pierdo porque no se si simplemente debo importar la clase curso desde la carpeta domain de cursos a la carpeta domain de estudiantes . Se que puede haber un modulo shared, pero veo que mas adelante voy a tener interacciones similares entre modelos y veo que si meto todo lo que se comparte en shared este modulo se volvería un caos. Es aquí donde pido ayuda para tratar de entender mejor como funciona en este caso.
@AlbertHernandez
3 ай бұрын
Muy buenas! Me alegro de que te estes animando a ir aplicando la arquitectura hexagonal en tus proyectos, te comento una posible solución a lo que comentas. Lo mas importante en este caso es entender las reglas del negocio con la que estas trabajando para ver como poner esa relación entre ambos módulos, y en base a eso ya ver que tiene mas sentido. Como bien comentas, en tu dominio tienes lo que son los Cursos y luego los Estudiantes que pueden ir haciendo cursos. En el caso de que mantengas un array de cursos en la entidad de estudiantes, eso va a implicar que cada vez que quieras obtener un estudiante, vas a tener que estar trayendote el listado de cursos que tiene, lo cual, ya nose ni es adecuado. Una manera de solucionar esto y conseguir tener una independencia mas grande entre los modulos de Cursos y Estudiantes podria ser el de crearte uno nuevo que se encargue de esta relacion que puede ser Matriculas. /proyecto │ ├── /src │ ├── /Cursos │ │ ├── /Domain │ │ ├── /Application │ │ └── /Infrastructure │ │ │ ├── /Estudiantes │ │ ├── /Domain │ │ ├── /Application │ │ └── /Infrastructure │ │ │ ├── /Matriculas │ │ ├── /Domain │ │ ├── /Application │ │ └── /Infrastructure La idea, es que ya sea este modulo de Matriculas el que se encargue de saber y de tener la relacion de que cursos estan tomando los distintos estudiantes, lo bueno de esto, es que incluso en esta entidad de matricula podrias tener cosas como, cuando se ha comenzado a tomar el curso, cuando ha finalizado, el estado para saber si esta en progreso, si ya ha acabado, la nota del estudiante... Como ves, haciendolo de esta manera conseguimos tener separado lo que son los cursos y los estudiantes y que puedan ir evolucionando de manera independiente, y luego, la gestion de toda esta conexion con todas las ventajas que nos ofrece en un modulo nuevo y lo mejor, sin tenerlo en una carpeta shared donde luego pueda ir creciendo demasiado y se vuelva dificil de gestionar Ya me dices que te parece esta propuesta, un saludo!
@luismontes79
3 ай бұрын
genial video, nuevo suscriptor 🎉
@Josevi-f8w
7 ай бұрын
Hola Albert, como siempre tus explicaciones son de 10. Quería aprovechar para preguntarte si conoces libros, en idioma castellano, los cuales poder leer para profundizar más en la materia de la arquitectura hexagonal, con ejemplos de código a ser posible. He visto que siempre se suele hacer referencia a los libros escritos por Robert C. Martin, pero a partir de ahí, no he encontrado mucho más (en castellano o traducido al castellano, me refiero). Saludos y, por favor, no dejes nunca de transmitir tus conocimientos.
@AlbertHernandez
7 ай бұрын
Buenas! Muchas gracias :D Pues libros sobre arquitectura hexagonal traducidos al castellano no conozco, pero si te recomiendo que si quieres profundizar mucho más sobre esto y en castellano le des un vistazo a los videos y cursos de Codely, son muy top y se aprende mucho
@pitosauriorex3674
11 ай бұрын
Sos una bestia! ningún video o page que haya investigado lo ha explicado de una manera tan eficaz como tú, grande! Nuevo sub aquí.
@AlbertHernandez
11 ай бұрын
¡Muchas gracias! Me alegra que os estén resultando útiles estos videos 💪
@dannyjesuszambranomera8233
Жыл бұрын
y el diagrama de clases de ese ejercicio ejemplo?
@luisperis6064
6 ай бұрын
Muchas gracias! Quizás, lo único malo es que no se ve en que fichero estás cada vez.
@AlbertHernandez
6 ай бұрын
Es un placer! Pues justo me lo comentaron varios subscriptores y ya lo he cambiado, para que así en nuevos videos si aparezca en que fichero estoy, gracias también por la sugerencia :D
@dmartinezbello
5 ай бұрын
Gracias por tu video, de casualidad tienes videos con trucos para usar el intelij? Trabajo con contenedores, API, servidores y trucos?
@AlbertHernandez
5 ай бұрын
Es un placer 😁 Pues tengo algunos videos de como usar IntelliJ para debuggear apps, poner docker en applicaciones de typescript, uso de testcontainers... dale un vistazo al canal y si ves algo que echas en falta me comentas para ir añadiendolo, un saludo! 👋
@jsebdev1539
9 ай бұрын
Gran video gracias! Un comentario, seria genial si en el editor que usas se pudiera saber en cualquier momento en el tiempo en que archivo estas. Aveces se me olvidaba y la unica forma de recordar era volver en el video para ver que archivo abrias. Si hay forma de verlo y no me di cuenta, porfa vor que alguien me lo diga. Gracias
@AlbertHernandez
9 ай бұрын
Muchas gracias! Pues normalmente yo esto lo tengo desactivado pero si crees que os puede ser util por lo que me comentas lo pondré para futuros videos, gracias por la sugerencia! Un saludo 😁
@maxsimus320
3 ай бұрын
algo me me pregunto es como se manejan las transacciones en esta arquitectura
@AlbertHernandez
3 ай бұрын
Pues hay varias maneras de solucionar esto, una que ultimamente vengo viendo y que me gusta bastante es la de utilizar un async local storage para guardarte la transaccion, y luego ya los repositorios que accedan a ella para poder usarla si esta disponible. Luego, como hemos comentado, el caso de uso es el que debe de garantizar la transaccionalidad de la operacion, por lo que podriamos añadir un decorador que se encarge de meter la transaccion en el async local storage, de manera que luego el codigo quede tal que asi: export class MyUseCase { @Transactional() handle(): Promise { ... } } Si no lo queremos tener en el caso de uso porque nos parece que es ensuciar la logica de la aplicacion con cosas de transacciones que son mas a bajo nivel, de la base de datos, podriamos llevarnos eso mismo pero ya por ejemplo a los controladores o incluso a middlewares, dependiendo de lo que tengamos. Tengo pensado crear un video sobre como hacer todo esto bien paso por paso, asi que ahi espero profundizar mucho mas sobre todo esto
@IvanAponza
6 ай бұрын
Master una consulta cuál sería la ventaja de no utilizar clases y sólo implementar interfaces en el la capa de dominio,
@AlbertHernandez
6 ай бұрын
Buenas Ivan! Pues depende mucho del caso, podrías usar también clases, al final cada pieza tiene su sitio. Yo por ejemplo lo último que estoy haciendo es definir lo que son los contratos de los repositorios en lugar de con interfaces con clases abstractas, porque luego esto por ejemplo me permite mockear de una manera mucho mas sencilla los repositorios con utilidades de typescript o me permiten hacer service discovery de estos elementos en el contenedor de dependencies de NestJS de una manera más sencilla que si utilizara una interface. Al final todo depende del caso de uso y lo mejor siempre es conocer las dos y utilizar la que más se va a adaptar a tus necesidades
@yorozuya6115
Жыл бұрын
que ocurre si quiero agregar un nuevo puerto de entrada, como un consumidor de kafka a la vez que express?
@AlbertHernandez
Жыл бұрын
La idea es que esos consumidores iran a la capa de infraestructura que es el componente que esta acoplados a ellos, luego estos sacaran los datos que necesiten y llamaran al caso de uso que ya estara totalmente desacoplado
@Josevi-f8w
5 ай бұрын
Hola Albert, te lanzo dos preguntas, por si me las puedes resolver... La primera: El directorio "dist" ¿Hay que generarlo desde el servidor de producción sobre el que se levante la aplicación, mediante le ejecución del script "npm run build"? Lo pregunto porque veo que dicho directorio está incluido en el gitignore, por lo que no se subirá al repo remoto. Y, la segunda: Cuando en mi servidor de producción instalo las dependencias definidas en el package.json, mediante el comando "npm ci", por consola me sale una error tal que así: > miapp@1.0.0 prepare > > husky install sh: 1: husky: not found ¿Sabrías decirme a que se debe? Se me ocurre, viendo el script "prepare" que tienes definido en el package.json, que igual el error se genera porque te falta anteponer a dicho script el comando npm, pero no estoy seguro... Saludos y gracias por adelantado.
@AlbertHernandez
5 ай бұрын
Buenas! Respecto al directorio "dist", normalmente este se tiene en el gitignore ya que lo mas habitual es trabajar con proyectos dockerizados, y seria ese Dockerfile el encargado de compilar y crear el directorio de "dist", por lo que no haría falta pushearlo. Respecto al error con husky, lo mas probable es que estes ejecutando el husky prepare en tu servidor de producción lo cual no deberías hacerlo, ya que husky es una herramienta pensada sobretodo para entornos de desarrollo, aqui tienes una issue que se creo en husky donde explican esto y te proponen varias soluciones: github.com/typicode/husky/issues/920 Espero que te sirve, de todas formas si tienes alguna duda mas y te puedo ayudar me dices y veo como te puedo ayudar.
@JoseVicentePerezGirona
5 ай бұрын
@@AlbertHernandez Muchas gracias por tu respuesta, Albert. Me ha sido de gran ayuda. ¡Saludos!
@alejandrob8215
4 ай бұрын
Hola Albert, es el mejor video y explicación por lejos que he visto; una consulta por favor, el email-sender, podría ser otro caso de uso el cual utilicen otros casos de uso? y porque se utiliza tan abstracto con interfaces la capa de dominio? muchas gracias por compartir tus conocimientos!! Saludos!!
@AlbertHernandez
4 ай бұрын
Muchas gracias ^^ Lo del email-sender que lo usen otros casos de uso puede ser, va a depender mucho de lo que tengas, podrias desde poner un servicio de dominio que se utilice en varios casos de uso o consumir directamente el otro caso de uso, pero cuidado luego con el acoplamiento entre ambos ya que puede llevar a problemas En la capa de dominio no tiene porque ser siempre tan abstracto, yo en este caso si que me interesaba poner esas interfaces para luego no estar acoplado en el dominio o aplicacion a ciertas implementaciones del cliente de email o por ejemplo de los repositorios para acceder a base de datos, pero tambien en esta capa podriamos meter servicios de dominio que no usen interfaces ya que no nos interesa. Como comento, va a depender mucho luego del caso que tengas, lo que siempre es recomendable es conocer varias formas de afrontar un problema y luego en base a lo que tienes elegir una opcion u otra
@alejandrob8215
4 ай бұрын
@@AlbertHernandez Muchas gracias por la respuesta, ha sido muy útil!! Saludos!!!
@danielpacheco2520
Жыл бұрын
Hay posibilidades de hacer este tipo de arquitectura con JS? y de ser asi podrias subir un video? gracias.
@AlbertHernandez
Жыл бұрын
Si claro, en JS tambien se podria conseguir, la principal desventaja seria que no tenemos las interfaces pero la idea es la misma, me apunto lo de hacer un video de esta arquitectura con JS para que veas tambien como seria :)
@danielpacheco2520
Жыл бұрын
@@AlbertHernandez estoy atento, recién encontré tu canal y he aprendido una barbaridad.. muchas gracias
@sisoyunrobot6413
Жыл бұрын
Hola Albert, la conexión con las base de datos, en este caso mongodb, en que parte iría, en la aplication? y los modelos
@AlbertHernandez
Жыл бұрын
La conexión con la base de datos, si está acoplada a MongoDB, iría a la capa de infraestructura, ya que al final MongoDB es una solución que estamos utilizando para almacenar de manera persistente los datos con los que trabajamos. En cuanto a los modelos, si son clases puras y no saben nada de MongoDB, irían a la capa de dominio. Sin embargo, si son modelos que están acoplados a Mongo porque utilizas decoradores u otras cosas, entonces irían a la infraestructura. Un truco que suelo utilizar para determinar si algo pertenece a la infraestructura o al dominio es mirar los imports que tiene el archivo. Si veo imports que no son nuestros y son de librerías de terceros como Mongoose, PostgreSQL, Bull, es casi seguro que van a la infraestructura :)
@jmizraim47
Жыл бұрын
@@AlbertHernandezya que cada entidad tiene su propia carpeta de infraestructura. Cada infraestructura de cada entidad debe haber una conexión a MongoDB?
@pedritoalejos3694
3 ай бұрын
Faltaron los puertos y adaptadores
@AlbertHernandez
3 ай бұрын
Buenas! En realidad si que los vimos pero no los llamé así, los puertos serian las interfaces que hemos creado en la capa de dominio y los adaptadores las distintas implementaciones de esas interfaces
@gamuro6977
2 күн бұрын
Hola hay algo que me preocupa y es el definir el email sender en el dominio. es correcto esto? me parece medio raro tener la lógica de email junto con el usuario. otra duda que tengo es si un caso de uso necesita de otra entidad debemos crear sus respectivas interfaces es decir duplicarlas
@AlbertHernandez
Күн бұрын
Buenas! En el dominio definiriamos lo que sería la interfaz de ese EmailSender para no estar acoplados luego a como enviamos emails, y ya sería en la parte de infraestructura donde lo implementemos. Si no lo pusieramos en la capa de dominio y por ejemplo solo estuviera en infra, esto no lo podríamos usar en las capas mas externas. Esto no significa que tengas que definirlo todo junto, si por ejemplo la logica de enviar correos es totalmente aislada de la de usuarios, podrias por ejemplo tener una carpeta shared donde poner aqui esta logica, con su respectivas carpetas de infra y domain. Respecto a que un caso de uso necesite de otra entidad, va a depender del caso concreto, pero si estan todo dentro del mismo contexto podrias tener varias entidades que interactuen
@gamuro6977
Күн бұрын
@@AlbertHernandez Hola muchas gracias por responder, la verdad es que me encanta la arquitectura y llevo estudiandola un tiempo, con respecto al email estaria bien definirlo en infraestructura y por ejemplo después de que el caso de uso registro el usuario entonces envio el email desde el controller? En cuanto a las entidades estoy implementando vertical slicing por lo cual tengo una capa de infraestructura para cada entidad y quería saber como relacionarlas
@AlbertHernandez
9 сағат бұрын
Yo lo haría en la capa de dominio, no en la infra, al final la logica de enviar un email al usuario cuando se registra es parte de como quieres que se comporte tu aplicación en terminos de negocio, no es logica de infra. Lo ideal en este caso seria que al registrar un usuario se publicara un evento de user-registred y entonces como consecuencia de este evento se enviara el email invocando a otro caso de uso. En el caso de que aun no estes trabajando con eventos ni nada lo puedes hacer en el controller, donde despues de llamar al caso de uso de registrar un usuario llamaras al caso de uso de enviar el mensaje de bienvenida
@SrDeo.
3 ай бұрын
Lo difícil, es hacerlo ver fácil... gracias por explicarlo con calma y claridad ... +1 Sub
@CodeWithDesign
Жыл бұрын
Sos crack Albert.. no hay videos de esto explicado asi
@CodeWithDesign
Жыл бұрын
Albert falta Redis y Express porque veo que no hay nada actualizado...
@AlbertHernandez
Жыл бұрын
Claro, me lo apunto y a ver si podemos hablar de eso en próximos videos :)
@gerardopacheco9521
3 ай бұрын
muchas gracias! que buen video de arquitectura
@zerdnelemo
Жыл бұрын
Desde express v4.16 en adelante puedes obviar la dependencia body-parser haciendo: `app.use(express.json());` en lugar de `app.use(bodyparser.json());` Muy buen video!
@AlbertHernandez
Жыл бұрын
Cierto, gracias por el tip! :)
@Deus-lo-Vuilt
Жыл бұрын
excelente , gracias albert , de casualidad tienes algun video creando un proyecto desde 0 usando solo clean code? ando practicando como organizar mis carpetas y archivos para llevar algo lo más ordenado posible qwq
@AlbertHernandez
Жыл бұрын
Pues desde cero no tengo, yo me suelo apoyar en un skeleton que tengo para crear nuevos proyectos que es este: github.com/AlbertHernandez/express-typescript-service-skeleton Pero si os interesa podemos crear un video donde comentemos como hacerlo desde cero (aunque al igual es muy largo ya que tiene muchas cosas de docker, linter, tests...) Te recomiendo que le des un vistazo a ese proyecto por si te puede servir de inspiracion para organizar las carpetas y archivos, seguro que se puede seguir mejorando pero ese me ha estado sirviendo mucho 😁
@RicardoGiovaniCotrinaCardenas
Жыл бұрын
Hola Albert, muchas gracias por tu gran aporte ante todo ! Lo que deseo comentarte es que, estaba estudiando un poco y los nombres que le das a las capas(infractructure, application y domain) pertenecen a la arquitectura por capas, pero los nombres de capas(interface, infrastructure y domain) es de la arquitectura hexagonal, entonces lo que has hecho es arquitectura hexagonal o arquitectura por capas? Me encuentro en una encrucijada jeje Espero puedas ayudarme por favor. Saludos desde Perú !
@AlbertHernandez
Жыл бұрын
Hola! Entiendo que puede haber un poco de confusión... voy a definirte cada cosa para que veas las diferencias: La arquitectura por capas es una manera de organizar el código en diferentes niveles (o capas, como indica su nombre), donde cada capa solo puede comunicarse con las capas que le siguen. Un ejemplo de esta arquitectura es la de 3 capas, donde se tiene la capa de presentación (por ejemplo, una API web), la capa de negocio donde se trabaja con los datos, y la capa de persistencia de datos (la base de datos). Aquí, por ejemplo, todo lo que tenga que ver con los loggers, los servicios de email, y demás irían a la capa de negocio ya que no están relacionados ni con el guardado de datos ni con la presentación de los datos en la API. Por otro lado, la arquitectura hexagonal (el nombre oficial es "puertos y adaptadores", aunque se le llama casi siempre "hexagonal") es una manera de organizar el código donde se intenta separar la lógica de negocio de la infraestructura y los detalles de implementación. Por ejemplo, en el dominio tendríamos la interfaz del logger o la interfaz del servicio de email, y luego se implementarían dichas interfaces en la infraestructura, tal y como hemos visto en el video. Espero que esto te sirva para entender la diferencia entre estas arquitecturas. Si aún tienes dudas me dices y vemos si lo podemos ver mas en detalle en otro video. ¡Un saludo! :)
@davidllanes1019
3 ай бұрын
Que buen video, no puedo creer que mire como 6-7 videos antes y no lograba entender claramente cómo funciona la arquitectura hexagonal
@AlbertHernandez
3 ай бұрын
Al principio es un poco complicada, sobretodo si es la primera vez que la ves y no la pones en practica, pero una vez ya estas trabajando a ella y asientas los conocimientos uff muy buena esta arquitectura
@pedritoalejos3694
6 ай бұрын
Muy buen video, lo que he visto en otros proyecto es que para los casos de uso, le ponen una extensión al archivo llamado sufijo “useCase”
@AlbertHernandez
5 ай бұрын
Gracias!! Si, yo también lo he visto, eso ya es mas decisión de equipo, si se decide poner el sufijo "useCase" a tope con eso 😁
@sanchezcarlos1986
Жыл бұрын
Si quisiera tener un caso de uso que devuelva todos los usuarios, ¿lo recomendable sería hacer otro controller con su propio método run para ello? Es decir, por cada use case, ¿tener un controller dedicado sólo a ese caso de uso?
@AlbertHernandez
Жыл бұрын
Hola! Pues eso depende mucho de cómo queramos diseñarlo, pero por ejemplo, yo sí lo haría. Al final, estás creando dos lógicas distintas que van a tener comportamientos diferentes. Por ejemplo, el método que devuelve solo un usuario lo más probable es que devuelva un 404 en el caso de que no lo encuentre. Sin embargo, el endpoint de devolver todos los usuarios igual no quieres hacer esa lógica y simplemente devolver un array vacío. Si no ves muy bien esto, lo que siempre puedes hacer es comenzar metiéndolo todo en el mismo controlador y luego, si ves que va creciendo mucho y te merece la pena ir separándolo, como te comento, va a depender mucho de cómo lo diseñemos
@holamundo2233
Жыл бұрын
Hola Alberto muchas gracias por compartir, tengo una duda , en la capa de dominio solo defino interfaces y modelado o tambien puedo crear funciones concretas? la capa de aplicacion hasta donde entendido es una capa para historias de usuario osea interaccion de nuestros actores con el sistema , y en la capa de dominio creo funciones concretas que sean propias del negocio. esto es correcto? me lio mucho con que responsabilidad poner en una capa y en otra .
@AlbertHernandez
Жыл бұрын
Hola! Te voy contestando en orden: 1. En la capa de dominio puedes definir todo lo que quieras, desde interfaces, clases, funciones... lo que tienes que tener en cuenta es que sean cosas que pertenezcan al problema (dominio) que estas resolviendo. 2. Correcto, la capa de aplicacion esta mas relacionada a las historias de usuario, es donde viven todos los casos de uso que vayamos a tener como puede ser registrar un usuario, obtener un listado de usuarios, comprar unos articulos... Es normal que te lies, a todos nos pasa incluso a los que tienen mas experiencia. Lo que puedes hacer es comenzar poniendo todo en la capa de aplicacion y luego cosas que veas que no tienen sentido propio en esa historia de usuario o que las vas a reutilizar en varios sitios, las puedes extraer al dominio
@jmizraim47
Жыл бұрын
Sería genial un ejemplo más completo, con más entidades y conexión a una bd real. 🥺
@AlbertHernandez
Жыл бұрын
Hehe tomo nota, la idea principal de este video era mostrar la arquitectura hexagonal y aqui ya daria igual el tema de la base de datos, todo se aplicaria de la misma manera, quiero ver si preparo algun curso completo donde monte una aplicacion desde cero con varias entidades, conexiones a base de datos, arquitectura hexagonal... aunque aun tardare un poquito ya que quiero hacer algo que sea de calidad buena :)
@angelbelaunde9704
Жыл бұрын
muy bueno tu video y super claro. Tendrás algún vídeo donde enseñas a crear ese template?
@AlbertHernandez
Жыл бұрын
Muchas gracias! Pues ese template se hace desde la config de GitHub, es solo activar un checkbox. Pero si tengo pensado hacer un video donde veamos como hacer generadores de proyectos automáticos con variables y demás, pero ahora mismo no está
@devstian
Жыл бұрын
Hola, apenas descubro tu canal y me ha encantado, me podrías decir por favor que setup tienes?
@AlbertHernandez
Жыл бұрын
Buenas, me alegro que te haya gustado en canal :) Claro, quizás en un futuro podamos hacer un video donde muestre mi setup mas en detalle pero te paso por aquí lo que tengo. Ten una cosa en cuenta, el setup que tengo es muy overkill solamente para ser programador, yo principalmente lo tengo por que me apasiona el mundo de la creación de contenido y dar una buena calidad. Si estáis también interesados podemos hacer videos en el futuro sobre equipos recomendados para distintos perfiles, pero bueno, allá vamos: - Ordenador: MacBook Pro 14 pulgadas, 2021. M1 Max 64 GB Ram - Ratón: Logitech MX Master 3 - Teclado: Apple Magic Keyword - Americano - Plata - Micrófono: Shure SM7B - Brazo micrófono: Rode PSA1 - Amplificador micrófono: Cloudlifter 1 - Interfaz de audio Focusrite Scarlett 4i4 3rd Gen - Monitor principal: BenQ PD2725U Monitor Designer - Monitor secundario: LG Ultrafine 5K (la colaboración que hizo Apple con LG) - Twelve South HiRise Pro, Soporte ajustable en altura - Twelve South BookArc para MacBook, Soporte de Escritorio Vertical - Cámara principal: Sony Alpha ZV-E10 - Cámara conferencias: Logitech Brio 4k - Luces: Logitech Litra Beam - Altavoz: Bose TV Speaker - BenQ ScreenBar - Elgato Stream Deck - Alfombrilla: Silent Monsters Alfombrilla ratón Ordenador tamaño XXL (900 x 400 mm)
@Tommy87351
3 ай бұрын
Michas gracias, el mejor video que he visto de arquitectura hexagonal
@AlbertHernandez
3 ай бұрын
Hehe muchas gracias!
@TheGreyOlorin
Жыл бұрын
Muy explicativo el vídeo y fácil de entender, has conseguido que tenga más ganas aún de replantear un proyecto que estaba haciendo para usar este patrón de diseño que me parece una maravilla, me suscribo sin dudarlo y espero más videos como este! Saludos y enhorabuena!
@juandavidblancovergara2279
Жыл бұрын
Muchas gracias, muy conciso y muy detallado. me suscribo
@juanisidorogarcia1699
Жыл бұрын
Con el pedazo video que te has marcado te van a llegar LIKES Y COMENTARIOS segurísimo!! estoy totalmente convencido ^^. Muchísimas, muchísimas gracias por compartir tus conocimientos!! Estoy deseando entender y afianzar muy bien esta arquitectura para llevarla a la práctica en proyectos personales y no había visto aún ejemplos como este tan bien explicados!! Me ha encantado de verdad!!. El tiempo que me tomo para hacerte este comentario no es nada comparado con lo que me has ayudado. Tienes suscriptor y nuevo usuario de tu canal. Ya me pondré a ver más de tus videos con mi cafelito para seguir aprendiendo 🙂 Si puedes agregar más ejemplos sobre esta arquitectura estaría genial!!! Es decir, misma temática, igual que este, pero con distintos casos de usos, conectado a distintas "infraestructuras", realizando casos con bbdd, fakes, apis fakes, incluso rabbit para eventos!... o conectarte con otras apps externas como integromat, firebase (en general), me fliparia todo ^^ estoy deseando aprender del tema. O pensando en otros temas, demostrar cuanto de seguro es programar asi VS programación "normal" por inexpertos o por personas que se quedan estancados... por decirlo de alguna manera XD. El contenido que hay en español en internet es demasiado justo y no he visto nada así, ejemplos cotidianos y básicos, que te permitan a base de repetir y ver casos prácticos, entender y afianzar conocimientos. Genial!! Muy agradecido ya que había leído y estudiado por mi cuenta, pero sin casos prácticos. Muchas gracias de nuevo!! Te deseo lo mejor en este canal!!
@AlbertHernandez
Жыл бұрын
Muchas gracias por estas palabras, me alegro mucho de ver como el contenido que vamos creando está aportando a la comunidad. La idea es que sigamos creando nuevos videos sobre conceptos generales, temas de caché, patrón repository, monorepos, eventos, bases de datos… con el objetivo de que se entienda bien esto por separado, ya que una vez entendido se puede aplicar no solo a la arquitectura hexagonal sino a muchas otras también. Había pensado crear también una especie de bootcamp donde se construya luego una aplicación desde cero aplicando distintos de estos conceptos y así se vea el potencial de juntar todo esto. Se vienen cosas chulas que espero que os gusten :)
@WizraiderRD
Жыл бұрын
Podrías hacer lo mismo, pero con Nestjs Framework?
@AlbertHernandez
Жыл бұрын
Claro, es un video que tengo pendiente lo que ocurre es que es un framework bastante intrusivo y se suele meter mucho en el dominio entonces estoy viendo bien como hacerlo, pero saldrá :)
@riloco22
Жыл бұрын
Albert, muy interesantes tus vídeos, excelente, un suscriptor más, una duda, en qué parte de la infraestructura irían los test, talvez si pudieras complementar unos test con MongoDb sería genial..
@AlbertHernandez
Жыл бұрын
Me alegro de que te parezca interesante, en el skeleton para proyectos con arquitectura hexagonal tienes un ejemplo donde estoy haciendo el test con el inMemoryUserRepository, en el caso de hacerlo con mongo sería en el mismo sitio. De todas formas me apunto que estás interesado en tema de testing y así lo podemos ver en futuros videos :)
@AliLopez
Жыл бұрын
Suscrito! Genial video! Muchas gracias!
@hassleribanez9462
Жыл бұрын
Hola Albert, buen video. En caso tal que una implementación en infraestructura, se necesita lo que devuelve el servicio tal cual. Por ejemplo un token o algo así. El caso de uso devolvería en ese caso un dto o como se manejaría ese caso?
@AlbertHernandez
Жыл бұрын
¡Buenas, gracias! No sé si entiendo muy bien tu pregunta, en el caso de que quieras pasar datos entre capas lo que hay que tener en cuenta es lo mismo, que desde la capa de dominio por ejemplo no se acceda a infraestructura y demás. Si por ejemplo tienes un controller (infra) que llama a un caso de uso (aplicación) y no quieres desde el controller hacer ninguna transformación sobre los datos, estaría bien que devuelva directamente el DTO que ha devuelto el caso de uso. Los DTOs nos vienen aquí muy bien para enviar datos y devolver respuestas entre distintas capas
@hassleribanez9462
Жыл бұрын
@@AlbertHernandez muchas gracias por tu respuesta, si mi duda es si está bien usar un DTO basándome en la respuesta que me da el consumo al servicio externo.
@SergioAndresSierraPayares
Жыл бұрын
No sé cuántas veces he visto este video pero es que me ha ayudado un montón! Muchas gracias!! .. adicional: Podrías hacer un vídeo acerca de los servicios de dominio? 🤔
@AlbertHernandez
Жыл бұрын
Me alegro de que te haya ayudado. Me encanta ver cómo vamos creciendo juntos y mejorando :) y si por supuesto, me lo apunto para futuros videos. ¡Un saludo!
@taders8327
Жыл бұрын
Muchisimas gracias Albert! Me aclaraste varias cosas que tenía suelta de la arquitectura, estaba esperando este video :) Saludos desde Arg🇦🇷
@AlbertHernandez
Жыл бұрын
Con mucho gusto :)
@miguecast
Жыл бұрын
Ey! Muy bien explicado! Estoy buscando un curso de arquitectura hexagonal con Express y Typescript, precisamente! Tienes alguno? En castellano hay poco contenido. Te has ganado otro subscriptor
@AlbertHernandez
Жыл бұрын
Buenas! Gracias :) pues por ahora no tengo ningún curso completo solo algunos sueltos pero estoy pensando en hacer uno donde se cree una aplicación desde cero mas compleja
@miguecast
Жыл бұрын
@@AlbertHernandez pues es un nicho porque no hay, en udemy hay contenido en portugués y no baja de 219 eur. Si haces el curso implementando patrones de diseño y Testing en el back, BEST SELLER fijo!
@AlbertHernandez
Жыл бұрын
Hehe tomo nota :)
@andreseduardorodriguezselv4577
Жыл бұрын
Que buena explicacion, muy clara muy precisa excelente felicitaciones
@AlbertHernandez
Жыл бұрын
Gracias! 💪
@sisoyunrobot6413
Жыл бұрын
Seria genial que hicieras el video completo desde como configurar ts con express y demás, pero igual excelente video. voy a suscribirme en caso saques el video, y sería genial un video de nest con arquitectura hexagonal
@AlbertHernandez
Жыл бұрын
Buenas! Te refieres a un video donde explique, por ejemplo, cómo crear este skeleton desde cero? github.com/AlbertHernandez/express-typescript-service-skeleton/tree/main Sí! Lo de la arquitectura hexagonal con Nest es algo que tengo pendiente, pero se está complicando un poco ya que está siendo difícil escapar del framework en este caso debido a lo intrusivo que es sobre cómo gestionar dependencias, los adaptadores propios del framework y demás... pero bueno, tocará investigar y aprender más para traeros una posible solución 💪
@sisoyunrobot6413
Жыл бұрын
@@AlbertHernandez Si lo del Skeloton desde cero estaría bueno.
@AlbertHernandez
Жыл бұрын
Apuntado! 😁😁
@neutro78
6 ай бұрын
llevas dos días ayudandome con tus tutoriales
@AlbertHernandez
6 ай бұрын
Me alegro que te sean de ayuda 😁
@codigito
Жыл бұрын
Muy chulo el video 😊
@pedrolosas8063
Жыл бұрын
Muchas gracias Albert!!! todo super claro!!
@AlbertHernandez
Жыл бұрын
Me alegro mucho, ahora a ponerlo en práctica, ahí seguro que surgen dudas pero cualquier cosa me dices, un saludo!
@marcoa.ramirez5752
7 ай бұрын
Contenido de calidad 💪
@AlbertHernandez
7 ай бұрын
Me alegro de que pienses eso 😁
@deimerpadillamendez3255
Жыл бұрын
De lo mejores videos que he podido ver
@AlbertHernandez
11 ай бұрын
Me alegro de que te gustara :D
@alexechavarria3283
Жыл бұрын
Increíble lo bien que lo explicas!!!
@AlbertHernandez
Жыл бұрын
Gracias Alex! Me alegra ver que todo esto se entienda, no son cosas muy sencillas y llevan su tiempo
@haqzel6476
11 ай бұрын
Me encantó el vídeo, muy bien explicado, felicidades.
Пікірлер: 171