Transcripciones
1. Introducción: Hola a todos y bienvenidos
al curso de Spring Boot. El mejor recurso en línea que necesitas para aprender Spring Boot desde cero y convertirte en un
mejor ingeniero de software. El marco Springboard es utilizado por muchas grandes empresas tecnológicas para construir sus
arquitecturas de microservicios y sistemas
back-end a gran escala, ya que le ayuda a construir una producción de
alto rendimiento
califique las aplicaciones mientras mantiene su base
de código escalable. Haber rociado en
nuestro conjunto de habilidades
le permitirá ser
más competitivo en el mercado laboral y definitivamente es
una tecnología requerida para dominar en su camino hacia convertirse un
software de back-end senior ingeniero. En este, nuestro curso, vamos a construir desde
cero una API de resto usando Spring Boot que
se comunique con una API externa vía HTTP, pero también con una base de datos MySQL
local para almacenar algunos datos de usuario. El objetivo de este curso es mostrarte cómo funciona Spring
Boot en una aplicación de extremo a extremo con funcionalidad similar
a un microservicio. Y ojalá esto te
dé ese poderoso inicio de tu viaje de
convertirte en una primavera con maestro. El único requisito para
este curso es tener idea
inteligente instalada conocimientos
básicos de Java, y por supuesto, un fuerte deseo de
aprender nuevas tecnologías. Entonces con eso, saltemos a la primera conferencia
de este curso.
2. ¿Por qué SpringBoot?: Hola a todos, Bienvenidos de nuevo. Entonces, antes de
sumergirnos en el código real, tomemos un momento
y entendamos por qué necesitamos aprender el marco
Spring Boot. Aquí mismo estamos
en el
sitio web oficial de ancho de resorte. Y si hacemos clic en el Resumen, podemos ver una serie
de ventajas de este marco que
en realidad son validadas
por la industria. Es decir, se agregan aquí
mismo en la página web. Pero la popularidad
de este marco en realidad dice algo sobre si esas ventajas que en
realidad son ciertas o no, ¿verdad? Entonces, antes que nada, sobre la popularidad, ¿verdad? Pero la razón por la que es tan popular es
porque es muy flexible y te permite crear aplicaciones de tasa de
producción muy rápido. Vamos a ver más
en este curso que primavera con es realmente
fácil de configurar, ya sea usando anotaciones
o archivos de configuración. Y también es importante
mencionar el panorama de aplicaciones donde se puede usar
Spring Boot. Podemos usarlo para
construir microservicios, que es un poco como el,
la nueva tendencia hoy en día. Casi cualquier gran empresa tiene esta
arquitectura de microservicios en alguna parte de su
infraestructura. Y Spring Boot tiene en realidad un soporte completo
para este Mosley. Si usa las capacidades de Spring Cloud y Cloud que
Spring Cloud realmente ofrece, um, pero aparte de eso, también
puede crear aplicaciones
reactivas
y aplicaciones impulsadas por eventos. Así que se integra con
prácticamente todas las cosas nuevas
que están pasando por ahí. Entonces, en otras palabras, si
sabes cómo funciona Spring, tienes una, a,
una ventaja en este mundo de la ingeniería de
software a partir de hoy. Así que hay una serie de
clips y documentación en internet que realmente
puedes seguir si quieres ver una visión general, o Palm Springs realmente funciona, mucha gente
realmente lo está usando. Entonces hay mucha
documentación en Internet. Y el papel principal de
este curso es
permitirte usar el trampolín
muy rápido. Entonces no vamos a
sumergirnos en todos los pequeños
detalles del trampolín. Sólo vamos a
empezar de inmediato y ponernos marcha con las principales capacidades
de Springfield, ¿verdad? Voy a suponer
que
no se puede tener programación orientada a objetos y cómo funcionan las cosas en ese espacio. Estoy en clases, interfaces, métodos y cosas así. Así conocimientos básicos de Java. Y luego vamos a
construir sobre eso con las capacidades del marco
Spring Boot.
3. Crea tu primera aplicación de iniciación primaveral: Así que basta platicar. Veamos algún código, ¿verdad? Si quieres construir tu
primera aplicación Spring Boot, tenemos dos opciones. El primero es usar este sitio web de inicializador de
primavera, que puedes acceder al
inicio Spring dot io. Y este sitio web le permite
crear una aplicación
Spring Boot preconfigurada. Solo tienes que dar click, seleccionar tu proyecto,
tu idioma, tu versión Spring Boot, y completar tu
nombre de proyecto grupo de artefactos y cosas así, incluyendo la versión Java. Y al hacer clic en Generar, vas a ver
que el navegador
descargará un archivo
con el proyecto en
un proyecto de idea inteligente que contiene una sencilla aplicación Hello
World con trampolín preconfigurado. Este es por supuesto el camino fácil, pero no vamos
a ir por esa ruta. En cambio,
vamos a partir de un
proyecto de idea inteligente limpia y vamos a agregar lo que se requiere en términos de dependencias de primavera para
ver cómo funciona realmente. Entonces aquí mismo tengo la idea inteligente,
Community Edition. Voy a dar click
en Nuevo Proyecto. Voy a decir curso
Spring Boot. Voy a seleccionar Java como lenguaje mayor sistema
como-construido. Voy a usar Java 17. Y aquí mismo
voy a decir Java dot, spring, spring dot course. Quiero presionar Crear
y vamos a esperar a que Gradle se actualice, para descargar todas las dependencias
iniciales. Y este es nuestro primer proyecto. Ahora vamos a
volver a la web y
buscar la web de
arranque de Spring Boot. Maven, Centro. Central es, por supuesto,
el repositorio principal para las dependencias basadas en JVM que
vamos a buscar para
esta dependencia se llama Spring Boot starter web. Esta es una especie de
dependencia delgada que incluye
prácticamente todas las cosas necesitamos para crear una aplicación
Spring Boot muy básica. Vamos a dar click
en la última versión y seleccionar Gradle. Y vamos a
copiar esto directamente en nuestro archivo Gradle acumulado,
la sección de dependencias. Voy a pegarlo aquí
y luego darle mayor actualización. Y luego podemos ver que se
descargó correctamente. Ahora voy a volver a la clase principal y aquí mismo en el nivel de clase y entrar en anotado con la aplicación Spring
Boot. Estos son rotación
proviene de, por supuesto, el
marco Spring Boot identifica el punto de entrada para nuestra aplicación
Spring Boot. Y en el cuerpo de
la clase principal, vamos a decir Spring
application dot run. Y aquí mismo
vamos a proporcionar el objeto principal de clase punto. Entonces este es un, este
es el identificador para la clase principal donde se encuentra
el resorte con
anotación. Entonces vamos a
aportar los argumentos que se aportaron
sobre el método principal. Entonces, lo que realmente
hace esta línea es comenzar, el marco real es básicamente
una instrucción de bloqueo. Entonces la aplicación, el proceso, proceso
JVM no saldrá hasta que la aplicación sea
asesinada o hasta que llegue, el proceso se termina de alguna
manera, ¿verdad? Cualquier aplicación Spring, quiero decir, cualquier servidor web en realidad debería ser de larga ejecución
porque debería aceptar continuamente
conexiones de clientes HTTP. Así que cuando hacemos clic en ejecutar, vamos a ver en
los registros esta salida. Para que puedas ver este bonito arte diciendo primavera así
como la versión primaveral. Y en los logs
podemos ver que tenemos aquí los logs del servidor web
Tomcat. Podemos ver el puerto en
el que se está ejecutando la aplicación, y podemos ver que se
inició con éxito. En otras palabras,
Tomcat es básicamente un servidor web que
viene con Spring Boot. Entonces también puedes
instalarlo de forma independiente, ¿verdad? Está construido por la comunidad
Apache y es básicamente un servidor web
clásico, solo acepta conexiones, sigue el protocolo HTTP
y todas las cosas. La razón principal por la
que se incorporó en el marco, creo, es
porque es muy ligero. Así que no consume demasiada memoria y
demasiada, demasiados recursos. Y probablemente esta fue la
razón por la que se eligió para formar parte del marco del
trampolín. Creo que también podemos
cambiarlo si quieres con Apache o catering u
otros servidores web. Así es como funciona en una versión
por defecto, ¿verdad? Bien, así es como funciona
realmente nuestra
primera aplicación Spring Boot . Actualmente la aplicación
no hace nada, solo acepta
conexiones en TDAH. Pero si vamos en nuestro
navegador y decimos localhost, local, solicit, host local TDAH, y simplemente hacemos clic en él. Podemos ver que
no tenemos nada. Este error en realidad
viene de Spring Boot o
de Tomcat, creo, porque necesita encontrar algunas rutas para mapear la
solicitud y por defecto, Patty no tiene
nada a qué mapear. Entonces actualmente nuestra aplicación
simplemente se ejecuta y no hemos especificado ningún tipo de acción a ejecutar en una
interacción en particular, ¿verdad? Entonces este es actualmente
el estado, ¿verdad? Simplemente tenemos una aplicación
que no hace nada. ¿Cómo le decimos a esta
obligación que necesita hacer una acción específica cuando los clientes están interactuando
con ella de una manera específica? Entonces, por esa razón,
vamos a crear una clase que se llama controlador, controlador
de descanso. Y vamos a
poner esa clase en un paquete dedicado llamado
controladores, ¿verdad? Acabo de crear paquete
y luego voy a llamar
a este controlador de usuario. Entonces, cuando se trata de una aplicación Spring
Boot, un controlador es el
primer punto de entrada para una solicitud en
la aplicación. Entonces, cuando los clientes están haciendo una solicitud que necesita
golpear la aplicación, generalmente golpeará primero
a un controlador. Entonces en base a la lógica
que define al controlador, la solicitud se propagará
en otros componentes, como veremos más adelante
en este curso. Entonces, para hacer una idea de
cómo funciona un controlador, vamos a crear un método
aquí llamado public void, en realidad public string get user. Este método es un método clásico muy
sencillo. Simplemente devuelve algo así como el usuario John Doe simplemente
devuelve una cadena. Y muy importante, este
método será anotado con get mapping
seguido de getUser aquí mismo. Podemos tener cualquier tipo de cadena que realmente
debería comenzar con una diagonal hacia adelante
porque necesita
tener una estructura similar a una ruta. Entonces, lo que
realmente hace esta anotación es
crear una ruta o una ruta
en nuestra aplicación. Entonces, cuando un cliente, ya sea un navegador
o cualquier cliente HTTP va a llamar a esa ruta. Este método se llamará justo dentro de nuestra
aplicación, ¿verdad? Entonces así es como
realmente funciona. Ahora volvamos a ejecutar
nuestra aplicación para que esos cambios
surtan efecto. Y vamos a darle a
Enter en este caso, ¿verdad? Así que como puedes ver aquí, tenemos esta
cuerda de vuelta, ¿verdad? Ahora, si hacemos clic en
Inspeccionar para ver la solicitud real, si vamos Así en la
pestaña Red y
pulsamos refrescar, podemos ver que el
navegador realmente lanzó esta
solicitud HTTP get en esa URL, localhost 80, 80 GetUser, el navegador por defecto, al actualizar cualquier página, hace esta solicitud get. En realidad hace, en realidad
inicialmente hace esta solicitud de obtención. Y luego puede descargar
algo de JavaScript de vuelta, que luego es ejecutado
por el navegador, que luego puede permitir
otras solicitudes y así sucesivamente. Entonces, en la práctica, esto
es aún más complejo. Pero en este caso de uso muy
simple, el navegador acaba de
lanzar una solicitud get en la que realmente golpeó nuestra API, que devuelve este objeto
string. Entonces así es como recuperas
los datos de nuestra API. Ahora bien, si solo hacemos clic aquí, si hacemos clic aquí
en la respuesta, podemos ver nuestra carga útil de cadena. Y si hacemos clic aquí de
nuevo en los encabezados, podemos ver que en los encabezados de respuesta también
obtuvimos esta información aquí. Esos encabezados en realidad fueron
agregados por el framework. Entonces no lo hicimos, no le hicimos
nada a esos datos
para que aparecieran aquí. Esos son los encabezados de solicitud. Y por el camino a seguir, eso es solo un tipo de entrada de
información de valor clave, ¿verdad? Y esto es lo que realmente agregó el navegador
Chrome sobre la solicitud a
nuestra aplicación. Ahora, por supuesto, podemos
cambiar esos encabezados usando los mecanismos Spring
Boot. Pero una
cosa muy importante a tener en cuenta es que su estructura, el nombre, el nombre clave de los encabezados, y los valores en realidad están regulados por el protocolo HTTP. Entonces el protocolo HTTP,
y por cierto, HTTP significa Protocolo de
transferencia de hipertexto. El hipertexto en realidad
se refiere a HTML, pero es más una
nomenclatura heredada porque
en realidad puedes transferir datos
binarios usando HTTP. Entonces HDP tiene una serie de reglas. Cualquier protocolo básicamente
tiene una serie de reglas que gobiernan
algún tipo de acción. En este caso, HTTP gobierna la comunicación entre
el cliente y el servidor. Por lo que se puede ver básicamente
todo tipo de detalles sobre la forma en que
debe fallecer el encabezado. Tus proxies realmente funcionan. Y en otras palabras, si un cliente y el servidor
respetan las mismas reglas, son capaces de comunicarse
correctamente usando las reglas del
protocolo HTTP, también el almacenamiento en caché. Pero el alcance de este
curso no es
profundizar en el protocolo HTTP porque es muy, muy complejo. Y hay muchos detalles
dentro de este tema en particular, tal vez para un
curso diferente en el futuro. Pero por ahora, vamos
a limitarnos a estos usos muy básicos
de este protocolo. Como breve resumen, cuando haces una
solicitud get a un servidor web, básicamente
estás
solicitando datos de él. Cuando haces
una solicitud posterior, estás entregando algunos
datos a ese servidor. En este caso,
definimos un buen mapeo, lo que significa que
instruimos a la API, el servidor Web, para permitir solicitudes
GET en esa ruta. También tenemos post mapping, lo que significa que instruimos al
servidor web para recibir datos de clientes externos
en una ruta diferente, por ejemplo, bordes. Y esto es lo
que vamos a hacer a continuación. En la próxima conferencia,
vamos a seguir construyendo este controlador de usuario para explorar aún más
esa interacción con clientes externos.
4. ¿Cómo podemos usar las solicitudes de POST?: Así que vimos la forma en que básicamente
podemos recuperar algunos datos de nuestra API. Ahora vamos a aprender y
jugar con este mecanismo de entrada, salida de Spring Boot, que es el controlador
y la configuración de mapeo. Una
cosa muy buena de probar con un navegador es si
tienes HTML devuelto
desde tu aplicación, porque el navegador
realmente renderizará el HTML. Si decimos algo
como HTML cerrado, y luego decimos cuerpo, claro que esto no lo es, esto
es solo para fines de prueba, solo para jugar para mostrarte que el navegador
renderiza el HTML, cualquier texto aquí. Entonces, si ejecutamos esto de nuevo
y recargamos la página, podemos ver que el texto es básicamente renderizado
por el navegador. En consecuencia, devolvemos HTML, pero el navegador lo
renderizará automáticamente. Ahora, cuando tienes servidor web
ya que normalmente transfieres datos en algún tipo de formato
como JSON o proto buff. Y realmente no
necesitas este tipo de interacción con el navegador, pero podría ser útil si
tienes este tipo de caso de uso, solo devolviendo HTML. Ahora, en lugar del navegador, vamos a utilizar el cliente HTTP
dedicado, que se llama carteros. Esta es básicamente
una herramienta que tiene esta agradable interfaz de usuario que nos
permite interactuar o probar una API con diferentes
tipos de solicitudes, tipos y diferentes
tipos de cargas útiles que pueden configurar de
una manera muy fácil. Entonces, cuando diseñas un servicio web, usualmente juegas con
este tipo de herramienta para ver cómo funciona y
para probar diferentes cosas. Entonces la misma
petición exacta que
hicimos desde el navegador, podemos,
podemos hacer desde Postman
diciendo localhost 80,
80 seguido por el usuario de Git. Y si haces clic en Enviar, puedes ver que
obtienes el HTML ejecutado, devuelto, ¿verdad? También puedes formatear y
responder de diferentes maneras. Así que ahora digamos que
queremos devolver una cadena de vuelta de nuestra API. Esa cadena debería ser en realidad la representación JSON
para nuestro objeto de usuario. Así que primero definamos un
modelo en nuestra aplicación. Voy a crear un nuevo
paquete llamado model. Aquí mismo, voy
a decir Modelo de usuario. Esta es la clase para nuestro usuario. Y dentro de él
vamos a tener String,
FirstName y LastName
privados. Y digamos que también necesitamos
proporcionar enteros una
membresía por d, ¿verdad? Que es una especie de usuario
premium platino o cosas como un solo nivel de
servidor en, en nuestra aplicación solo
para probar cosas alrededor. Entonces vamos a agregar, primer lugar, un constructor. También vamos a agregar getters y setters para
todos los campos, ¿verdad? La idea inteligente nos ayuda a
hacer esto muy, muy bien. El único controlador
vamos a devolver un modelo de usuario, ¿verdad? Tenemos que importar esa clase. Y aquí mismo cuando
regresemos eso, tenemos que decir Nuevo modelo
de usuario de John Doe y 1234, ¿de acuerdo? Por supuesto, jugamos con
clases en el mundo real, jugamos con modelos de
objetos reales. Entonces por esa razón tenemos que experimentar con eso también. Entonces cuando le pegué enviar
en la respuesta, recuperamos este JSON. Entonces, como pueden ver, el,
el marco realmente convirtió nuestro objeto en adyacente, básicamente el, nuestro objeto, un modelo gut serializado en formato
adyacente, ¿verdad? Y esto se hizo automáticamente por la
primavera sería marco. Ahora bien, si volvemos
al controlador, podemos tener una situación en la
que necesitamos
devolver diferentes usuarios en
base a un ID, ¿verdad? Entonces, por ejemplo, digamos que
tenemos aquí un mapa, mapa privado de cadena
a UserModel, ¿verdad? Llamar a este usuario mapa nuevo HashMap. Bien, y digamos que agregamos un pequeño controlador
aquí mismo, controlador de usuario público. Y en este mapa
tenemos dos usuarios. Digamos, digamos en
el mapa de usuario que agregamos, ponemos en primer
lugar al usuario John, que tiene esto, este
modelo aquí mismo. Y luego también ponemos a
la usuaria Jane e.g y esta es Jane Doe con
diferente membresía por d. así que básicamente tenemos esos
dos usuarios en este mapa. Y cuando queremos obtener
el usuario de nuestra API, queremos obtenerlo
dependiendo del nombre, ¿verdad? Y esto significa que el nombre debe ser proporcionado
en la solicitud. Entonces el cliente realmente
debería agregar aquí un nombre que
puede ser una variable. Y este debería
llamarse nombre de usuario, ¿verdad? Esta es la forma en
que nos especificas, en una ruta, el hecho de que
quieres extraer una
variable de ella. Entonces aquí mismo en el nombre de usuario, necesitamos agregarlo también
en los parámetros de este método usando la anotación de la variable
path. Aquí necesitamos especificar
el tipo de la variable
y el mismo nombre exacto que
agregamos en la ruta, ¿verdad? Entonces cuando haces una solicitud, si dices getUser John directamente desde el navegador
o desde cartero, El valor de John
se propagará en esta variable de nombre de
usuario. Y podemos usarlo como
cualquier otra variable. Entonces en este caso
podemos decir mapa de usuario punto get of username, ¿verdad? Entonces volvamos a ejecutar esto. Y en realidad voy a
también golpear Debug y poner un punto de interrupción
aquí mismo para ver que esta variable se
rellena correctamente. Entonces comenzó la aplicación. Voy a volver
a cartero y decir getUser punto John y
golpear Enviar y arroz, podemos decir que la
variable username tiene el John válido, y solo va a
entrar en el mapa y devolver el real objeto, ¿verdad? Entonces voy a
golpear Next y volver. Podemos ver que
obtenemos lo mismo. Ahora si usamos chain, podemos ver que las
variables para que jueguemos correctamente y golpeemos F9, y podamos ver que
obtenemos los otros objetos. Entonces esta es la forma en que
ustedes básicamente proporcionan algunos datos a la
aplicación en la ruta, en la ruta de solicitud para que puedan seleccionar diferentes
tipos de información. Esto puede ser un ID de usuario, puede
ser un correo electrónico, puede
ser cualquier cosa así, cualquier cosa que realmente
tenga sentido en tu aplicación. Ahora cambiemos de marcha y juguemos con alguna pausa a las solicitudes, que es la forma en que un
cliente puede proporcionar datos a una aplicación. Para la aplicación Spring Boot, queremos crear un usuario, ¿verdad? Vamos a decir crear usuario. Cuando creamos un usuario, no
queremos
tener nada de vuelta, pero quieres actualizar
este, este contrato. Segundo, vamos a decir
aquí, post mapping, ¿verdad? Porque queremos
proporcionar algunos datos
a nuestras webs están en que los datos deben ser los
datos del usuario, ¿verdad? El FirstName,
LastName, y así sucesivamente. Entonces vamos a decir
Add User, y eso es todo. Y aquí mismo en los
parámetros que necesitamos para proporcionar algo así como
respuesta, solicitar cuerpo. Esta anotación
le dice a Spring Boot que necesita
extraer algunos datos del cuerpo de la solicitud y
colocarlos en un objeto. Ese objeto debería ser por ejemplo el modelo de usuario, ¿verdad? Entonces esto significa que en el mapa del
usuario podemos decir put y podemos decir user
dot get firstName seguido del objeto real. Sí, no tengo que devolver
nada aquí, ¿verdad? Porque el método no
tiene ningún tipo de retorno. Entonces en otras palabras, estoy extrayendo el modelo de
usuario de la solicitud y
lo estoy poniendo en este mapeador de usuarios. Hagamos esto. Y la primera vez voy
a probar con un depurador para ver que el objeto de usuario
está poblado correctamente. Sí, así se inicia la
aplicación. Entonces voy a crear
una solicitud de publicación. Voy a hacer una nueva
pestaña aquí en Cartero. Y voy a seleccionar
aquí post, derecho. Voy a decir Add User. Y aquí mismo en el cuerpo, voy a decir tu fila, y voy a seleccionar la
aplicación JSON json aquí mismo. Necesito proporcionar adyacente que contiene la
información real para el usuario. No quiero crear
que Jason deba seguir el esquema de ese objeto
o el objeto modelo de usuario, ¿verdad? Por lo que debe transmitir
el nombre, apellido y la identificación de
membresía. Simplemente puedo obtenerlos
de la otra pestaña. Y claro que los
voy a
poblar con diferentes valores, por ejemplo Daniel, Craig. Y este debería ser un valor
como cualquier entero que queramos. Si hacemos clic en Enviar, podemos ver que obtenemos un error
llamado error interno del servidor
o sucedió algo. A ver qué pasó. Entonces, si vamos
aquí mismo en los registros, podemos ver que no se puede construir una instancia de modelo de usuario, no existe ningún creador como
constructor predeterminado. Entonces esta es una flecha que
probablemente puedas ver bastante
a menudo en realidad, si juegas con objetos,
con serialización, deserialización,
cosas así,
que en realidad
nos dice que cuando proporcionar este Json, ¿verdad? Y la primavera con el
recibe ese Json, básicamente
trata de
crear un objeto modelo de usuario. Pero cuando intenta crear
este objeto de modelo de usuario, no usa este
constructor, ¿verdad? Que tiene esos
tres parámetros. En cambio, lo que espera, espera tener
un constructor
sin parámetros para simplemente
crear una instancia. Y luego espera usar los métodos setter para establecer todos esos tres
campos uno por uno. Esto es lo que
realmente espera el marco de la civilización
Jackson , ¿verdad? Este es el componente
dentro del trampolín que se ocupa de la serialización
y deserialización. Entonces, en otras palabras,
solo tenemos que proporcionar aquí un constructor por defecto
sin parámetros. Y funcionará creando de nuevo, ejecutando nuevamente la
aplicación con modo de depuración. Debió haber comenzado. ¿Bien? Ahora, volviendo a Cartero
y da clic en Enviar, y dice que
tenemos una mala solicitud. Veamos cuál es el
error ahora dice JSON parse error
valor numérico está fuera de rango, ¿verdad? Entonces parece que este
número que agregamos aquí está fuera del rango
entero, así que solo tenemos que agregar un número
menor aquí, ¿verdad? Ahora si pulsamos en Enviar,
podemos ver que funciona. Entonces, si hacemos clic en
este parámetro de usuario, podemos ver que se rellena
con los valores correctos. Y si hacemos clic en F9 para
continuar con la ejecución, el valor debe ser
almacenado en el mapa. Entonces, si estoy usando la otra pestaña
para llamar a getUser for Daniel, podemos ver que
recuperamos la respuesta adecuada. Entonces así es como realmente
agregamos datos a nuestra API.
5. Implementación de respuestas estándar: Una cosa que también
quería mencionar sobre funcionalidad de
estos controladores es que normalmente cuando
juegas con microservicios, necesitas poder especificar el estado correcto para tu
introducción para tu solicitud. En este caso, podemos ver
que solo tenemos Status 200 para todas las solicitudes que
hicimos es esta es la predeterminada, status a 100, ¿bien? En HTTP, protocolo significa que la interacción
ocurre con éxito y todo funcionó bien. Ahora también se puede buscar
el estado HTTP está en línea, y esta es la lista completa de estados que son mencionados
por un protocolo, ¿verdad? Entonces, por ejemplo, si tienes
estado 500-599, eso debería ser un error del servidor. Las respuestas exitosas son 200-299. Y esta voluntad también tiene todo tipo de estatus es como
si respondes con 201, esto significa que creaste
el recurso con éxito. Todo tipo de modelos de
interacción que sucedieron en tu
aplicación, ¿no? Tan bien diseñado. Los servidores web, las respuestas y el estado es de tu
aplicación deben reflejar lo real que sucedió en tu aplicación
a través de este código de estado. Y en primavera tendríamos
una manera de hacer esto en los controladores usando un objeto que necesitamos devolver
en cada método, que se llama entidad de respuesta. Y esta entidad de respuesta
es de tipo genérico. También podemos agregar aquí
http status object e.g. y lo que esto realmente
significa es que podemos devolver de ese método
algo como return, response entity,
response, entity, dot accepted, dot built
responsabilidades. Sigue un patrón constructor. Y cuando decimos aceptado aquí, significa
que agregamos este estado
HTTP aceptado, que es 20.2 en la
respuesta, ¿verdad? Construimos este objeto. Así que básicamente ahora cuando ejecutamos la aplicación y
creamos un nuevo usuario. Entonces ahora cuando vamos y carteros
otra vez y decimos Add User, y proporcionamos aquí algunos datos. Hacemos clic en Enviar. Podemos ver que en
la respuesta
llegamos a cero para aceptarlo, ¿no? Que es un código de estado
que agregamos aquí mismo. Esto por supuesto, para
la mejor práctica de su, de su aplicación ¿verdad? Ahora, lo mismo se puede hacer aquí y por todas partes
en tu aplicación, en cualquier controlador deberías tener este tipo de interacción. También hay que mencionar que
el controlador interno, también
puede tener otro
tipo de métodos, ¿verdad? También gestionado por el protocolo
HTTP, por ejemplo, si buscas métodos HTTP, en realidad este,
puedes ver que aquí
obtenemos una serie de
métodos, ¿verdad? Así que hasta ahora usábamos los métodos
GET y post. Pero también puedes tener
cabeza PUT, eliminar, conectar opciones, charolas, parche, y esas son todas ellas. ejemplo, si queremos
usar delete, ¿verdad? Si queremos
eliminar a un usuario, por ejemplo solo
tenemos que ir aquí mismo, copiar este método,
decir eliminar mapeo. Y aquí mismo necesitamos
identificar al usuario, por ejemplo tenemos que decir eliminar usuario
seguido de un nombre de usuario, que de nuevo es un parámetro de
variable de ruta, ¿verdad? Entonces podemos decir aquí, eliminar seguido del nombre de usuario, lo que significa que simplemente sacamos
al usuario de nuestro mapa. Y cuando devolvemos la entidad de
respuesta, solo
podemos decir
eliminada o nutrición si hay algún estado
sin contenido, se
puede usar para
operaciones de eliminación, ¿verdad? Entonces, si acabamos de recargar
la aplicación ahora, y por cierto, cuando
reiniciamos la aplicación, que es la única forma de que
los cambios surtan efecto,
el mapa se vuelve a vaciar, así que solo esos dos usuarios lo harán ser agregado desde el
constructor, ¿verdad? Entonces, si agregamos algunos usuarios y luego detenemos la aplicación
y reiniciamos nuevamente, los nuevos usuarios no estarán en el mapa cuando
se reinicie la parte superior, ¿verdad? Porque por supuesto está
almacenado en la memoria. Entonces veamos, queremos recuperar
al usuario Daniel
debería estar aquí, en realidad ahora, o necesita
ser el usuario John, ¿verdad? Entonces este es el usuario, y ahora queremos eliminar. Entonces queremos crear una
nueva pestaña y decir Eliminar. Este es el método de solicitud de
eliminación de tipo de solicitud para ser más precisos. Y voy a decir
borrar usuario
seguido de John, escribir, borrarlo. Dice a cero por ahora contenido, lo que significa que el
elimina lo que tiene éxito. Y después voy a hacer clic en Enviar nuevo para que el usuario John. Nuevamente, veo que
no tengo nada. También podemos por supuesto, remodelar esto un poco
para decir algo así como si el mapa de usuario contiene nombre de usuario
clave, entonces voy a
devolverlo directamente. De lo contrario voy
a decir devolver una entidad de respuesta punto
no encontrada, construida. Y aquí por supuesto
necesito devolver una entidad de respuesta de modelo de usuario. Y aquí necesito decir entidad de
respuesta de ésta. Y esto debería ser
en realidad un opcional, opcional fuera de este. Entonces en otras palabras, si tengo al usuario en el mapa, devuelvo el usuario real. Pero si no lo
hago, voy a regresar no encontrado, que es 404, ¿verdad? Entonces volvamos a ejecutar la
obligación de
ver esta
inacción de funcionalidad, ¿verdad? Entonces voy a recuperar a
un usuario John. Puedo ver que lo tengo
porque acabo de reiniciar aplicación y los
datos poblados arrojaron. El constructor
en realidad está en el mapa. Ahora, quiero eliminar a
un usuario John, ¿verdad? Cuando me devuelva el usuario John, puedo ver que tengo 404
no encontrado, y no 200. Bien. Esta es la forma en que
podemos, por supuesto, actualizar el estado HTTP para reflejar la operación correcta que tuvo lugar en
otra aplicación. Muy bien, así que con eso, aprendimos sobre la forma en que
podemos jugar con los controladores, la forma en que podemos obtener algunos
datos de los clientes
de SAP, de Postman, y
también la forma
en que
podemos recuperar los datos de una manera adecuada. Ahora, cambiemos de marcha y
hablemos de servicios en el marco
Spring Boot.
6. Creación de servicios en Spring-Boot: Bien, bienvenido de
nuevo. Así que hasta ahora trabajaremos con
el controlador de resto. Vimos la forma en que podemos agregar y obtener información de
nuestra aplicación Spring Boot como cliente HTTP y también jugar con Postman para
lanzar sus solicitudes. Ahora vamos a continuar con un cambio estructural sobre aplicación porque como
mencioné inicialmente, un controlador de descanso es el
punto de entrada de su aplicación. Por lo que le permite
especificar cómo debe obtener los datos de sus
clientes y también cómo debe devolverlos. Pero generalmente esos componentes
deberían reenviar la interacción dentro su aplicación en
otras estructuras. En otras palabras, no
debes agregar lógica de
aplicación
o no deberías conectarte a una base de datos desde
tu controlador de riesgos. Solo debes obtener los
datos en el modelo que
quieras y luego llamar a un componente
diferente, una clase diferente donde se debe ejecutar
tu lógica, ¿verdad? El primer componente de este
tipo en el que nos vamos a sumergir ahora mismo
se llama servicio. Entonces vamos a crear aquí un nuevo paquete llamado servicios. Puede parecer que estoy creando aquí un paquete para cada clase, pero en realidad estoy creando un paquete para cada
categoría de clase. Porque si quieres
agregar tus modelos, tienes un paquete dedicado para esos mismos cuatro controladores, servicios y otros aspectos. Por lo general debes
estructurar tu código esta manera para
que sea escalable. Entonces voy a llamar a
este servicio de usuario. Ahora, un servicio en Spring
Boot es solo la clase anotada con la anotación de
servicio. Y lo que
realmente hace esta anotación es permitir que su aplicación se vea en el
marco de inyección de dependencias de Spring Boot, o registre su
clase en esa configuración. Entonces en otras palabras, si hacemos clic en esa
interfaz para ver qué hay detrás de ella o para
ver la implementación. Podemos ver que esta notación es básicamente una interfaz
porque así es la forma en que puedes crear
anotaciones en Java. Y también tiene esta anotación de
componentes, que es la anotación raíz en Spring Boot y
también otras. Ahora bien, el único papel funcional de esta anotación es el
que mencioné
anteriormente, ¿verdad? ¿Registra la clase en el marco de
inyección de dependencias? Y también tiene un papel
informativo, ¿no? Te dice que se
espera que esta clase haga algún tipo
de lógica de cálculo, ya sea llamando a servicios externos
o hacer algunas validaciones, o hacer cualquier tipo de lógica que tenga algo que ver
con el usuario gestión. Así que vamos a mover
esta parte aquí mismo con el almacenamiento de mapas de usuario a este servicio de usuario y también a esta
inicialización en particular. Lo vamos a poner en
el controlador de servicio al usuario aquí mismo. Y claro que no vamos a tener acceso a ese mapa en
el controlador ahora mismo. Necesitamos crear algunos métodos que reflejen los que tenemos
en el controlador resto. Para habilitar esta separación, vamos a decir public,
public, userModel, getUser. Y vamos a tener
aquí el nombre de usuario, ¿no? Entonces vamos a decir
nombre de usuario punto todavía. Entonces esta es una clase regular, no tiene nada que ver específico con el controlador de
resto, por lo que no tenemos que devolver una entidad
de respuesta de los servicios. Esta es una clase que, que se conecta a la forma que obtenemos datos de nuevo en
el cliente HTTP. Entonces tiene un
nivel de marco moral están bien. Pero en un servicio o
en un genéricamente en, en cualquier clase de componente, podemos agregar cualquier tipo de código Java simple
básico. Entonces este es GetUser. Lo mismo para el usuario de AD. Necesitamos tener
aquí un modelo de usuario. Y aquí mismo cuando
dices Put de usuario, y aquí podemos decir vacío
o algo así. Por supuesto tenemos que
decir aquí user.name, firstName, y luego user. Y no vamos
a devolver nada. Y también tenemos
eliminar usuario, ¿verdad? Entonces vamos a
decir eliminar un usuario por nombre de usuario, nombre. En realidad, vamos
a decir eliminar nombre de usuario. Ahora bien, la pregunta principal sería, movemos esa lógica a esta clase de servicio al
usuario, ¿verdad? ¿Cómo trabajamos con esta
clase desde nuestro controlador? Porque necesitamos tener
en la instancia del servicio
al usuario en
nuestro controlador, ¿verdad? Para poder hacer
exactamente las mismas cosas, ¿verdad? Agregar, eliminar o usuario. Entonces la forma en que hacemos
esto es primero, quiero decir,
en realidad hay dos formas. Uno que no se recomienda
en uno que se recomienda. Entonces el primero
sería crear una instancia del servicio al
usuario, ¿verdad? Ya sea a la derecha de nivel superior, como campo privado o en
el constructor escribir. De esta manera,
creamos manualmente esta instancia, ¿verdad? Entonces, mientras el
controlador
se vaya, tendrá una instancia. Esta es una forma en la
que funcionaría. Pero aún así, si necesitamos tener, si el servicio de usuario tiene un constructor derecho en el
futuro, digamos, bien. Un servicio público al usuario, ¿verdad? Y aquí mismo
necesitará algún tipo de otra clase que se refiera
únicamente a la administración de usuarios, por lo que no tiene nada que
ver con los controladores. Entonces necesitamos actualizar este
constructor aquí mismo, esta llamada aquí mismo, derecho, para poder obtener
esa dependencia,
ese servicio de validación, por ejemplo y proporcionado aquí mismo
en esta construcción, este problema se está
dando más grande, ¿verdad? A medida que se agregan más parámetros porque ya no tendríamos
ningún tipo de desacoplamiento
entre la lógica de procesamiento de usuario y las clases de
entrada y salida, ¿verdad? Entonces estamos mezclando preocupaciones si hacemos este tipo de
enfoque aquí mismo. En cambio, la
forma recomendada de jugar con instancias genéricamente en primavera es
usar la configuración de
inyección de dependencia del resorte. Así que la primavera con tiene este
patrón muy interesante que también
se puede encontrar en
marcos externos como juice, por ejemplo Google juice, que se llama
la inyección de dependencia. Y esencialmente un marco de
inyección de dependencia es solo una forma de obtener instancias en nuestra aplicación una manera desacoplada sin
usar la nueva palabra clave. Porque cada vez que
usas la nueva palabra clave, llegas a este problema donde
cuando necesitas la clase, también necesitas proporcionar todas
sus dependencias, ¿verdad? Y esto es problemático, va a esta preocupación
mezclando problema y dependencia
marco de inyección permite
abordar ese problema de una
manera muy limpia. Entonces en otras palabras, lo que tenemos que hacer
aquí es decir, es crear básicamente
un servicio de usuario
variable de nivel privado , y agregarlo en este
constructor aquí. Y entonces podemos decir este servicio de
punto igual servicio, o podemos cambiar el nombre de éste. En realidad sabe que aquí
estamos hablando de
diferentes variables. El nivel de alcance uno y
el nivel de clase uno. Pero qué hace, es que cuando se está
instanciando al controlador de usuario, ¿verdad? Entonces, cuando el, cuando el marco crea una instancia de la
clase de controlador de usuario en avisos de que este controlador de usuario necesita
un objeto
de servicio e intenta crear una instancia de la clase de servicio de
usuario. Y esto sucede
detrás de escena. No hace falta que te
preocupes por esto. Y dice que el
servicio de usuario no tiene ningún parámetro constructor
y solo crea la instancia como lo
harías tú, la nueva palabra clave. En cambio, si el servicio de usuario tuviera algún parámetro
en
el constructor, el framework
continuaremos y buscaremos e intentaremos crear una instancia para esos
parámetros también. Y va a ir así
recursivamente, ¿verdad? Hasta que logre
crear todas las instancias
que necesitan ser resueltas. Si puede lograr
crear una instancia, simplemente
fallará en
el tiempo de compilación. Eso es
algo muy útil porque puedes verlo enseguida. Entonces veamos eso en acción. Entonces obtengo este
Servicio de Usuario aquí mismo. Y por supuesto puedo
usar la
llave Contiene o metal ahora mismo porque es interna para
el servicio al usuario. Así que en cambio solo voy a decir entidad de
respuesta de servicio al usuario, en realidad service dot
get users by username. Y en este caso, tengo que asegurarme de que GetUser devuelva null o
algo así. Si no tengo la
clave en el Agregar Usuario, solo
tengo que buscar
servicio punto add usuario del modelo de usuario que
obtuve de los parámetros. Y lo mismo tengo que decir
para la eliminación. Así que borra usuario por nombre de usuario. Así que ahora mismo vamos a
ejecutar nuestra aplicación en realidad, vamos, vamos a asegurarnos de
que compila primero, ¿verdad? Entonces vamos a
escuchar la depuración para ver un poco cómo
se está instanciando este controlador , ¿verdad? Entonces como puedes ver, el
servicio de usuario tiene una instancia. El framework creó esto,
esta instancia de servicio de usuario. Para nosotros, este es el framework de
inyección de dependencia que creó esta
instancia automáticamente. Y es muy conveniente, ¿verdad? Solo hay que proporcionar esto en el constructor, y eso es todo. No tienes que
preocuparte por cómo se crea esa
instancia. Por supuesto, vamos a ejecutarlo para
ver que todavía funciona en la funcionalidad debería
ser la misma, ¿verdad? Entonces me sale el usuario John. Puedo ver que funciona. Agrego un usuario, Daniel Craig. Llegó a cero para aceptarlo. Solicito por el usuario Daniel. Me lo devuelvo. Borro al usuario
John. Funcionó. Y entonces si vuelvo a preguntar
por John, parece que no
tengo al usuario John. Veamos qué pasa. Por lo general, cuando tienes 500, algo salió mal, ya sea
una excepción de puntero nulo o algo así. Sí, en realidad tenemos
esa NullPointerExcepción. Entonces en el getUser, podemos ver que
obtenemos off opcional. Este realmente arroja si
tienes un valor nulo aquí. Entonces tenemos que decir fuera anulable. Entonces, cuando dices
opcional de nullable, si proporcionas null aquí mismo, simplemente
transformará esto
en un opcional de vacío. ¿Bien? Intentemos ese flujo otra vez para ver cómo funciona esta vez, ¿verdad? Entonces me sale el usuario John, ahora lo borro. Y aquí mismo cuando llegue, lo
recupere, puedo
ver 404 Not Found. Derecha. Entonces así es como funciona. Entonces sí, así es como el marco de inyección de
dependencia. Funciona detrás de escena
en un trampolín. Ahora quiero
mostrarte una mejor práctica que realmente necesitas
interiorizar porque es absolutamente obligatorio
cuando juegas con co-diseño y crearás
servicios y jugarás con
Spring Boot en general, que es que normalmente tienes
que depender de las abstracciones, tus clases, y no
de clases concretas. Y si echamos un
vistazo aquí mismo, podemos ver que la clase de controlador de
usuario depende de la clase de usuario, la clase de servicio de usuario, que es una clase concreta. En lugar de tener eso, necesitamos crear una interfaz
llamada realmente primero, necesitamos cambiar el nombre de la clase de servicio de
usuario en la
implementación de servicio de usuario I MPL. Sólo voy a
hacer eso corto. Y aquí mismo
voy a crear una interfaz llamada
User Service. Y ese servicio al usuario debería
contener esos métodos. Obtener usuario en usuario y
eliminar el vacío de usuario. Y éste debería
ser modelo de usuario, ¿no? Esa interfaz, por supuesto,
debe ser implementada por la implementación del
servicio de usuario. Como puedes ver, la
idea de IntelliJ resalta el hecho que implementamos
esa interfaz ahora. Y esta es la idea central
detrás de esta estrategia, es que en el controlador de usuario, voy a solicitar
la interfaz, la interfaz de servicio de usuario, y no la implementación. Y Spring Boot
hace lo siguiente. Cuando se trata de instanciar
un controlador de usuario, mira en el constructor, ve
que
necesita una interfaz, y en realidad interpreta
esto de la siguiente manera. Entonces la
clase de controlador de usuario tiene una dependencia de una clase que implementa la interfaz de servicio de
usuario. Por lo que intenta buscar una clase que implemente
la interfaz de usuario. En este caso,
tenemos una sola clase que implementa la interfaz de servicio de
usuario. E irá a crear
una instancia de eso. Si tienes varias clases implementando la misma interfaz y estás pidiendo una
interfaz y una clase, entonces necesitas
ser más explícito en qué clase quieres
realmente, ¿verdad? Y lo haces usando
la anotación calificador. La anotación de calificador
solo le
permite agregar una cadena y una cadena
que desee agregar aquí. Esa cadena también se debe agregar cuando se solicita una
instancia de una clase, pero también cuando se
crea esa clase, derecha, en la definición de clase. Entonces, si tienes dos clases, implementa la misma interfaz. Es necesario agregar un calificador
para ambos para
que la primavera sepa cuál debe
proporcionar en qué lugar. También puedes experimentar y ver cómo funciona esto en
acción con dos clases. Entonces así es como realmente
deberías construir un servicio en un grado de producción, digamos implementación. También ayuda
con las pruebas porque cuando intentas
probar el controlador de usuario, necesitas crear una nueva instancia de controlador de
usuario. Pero cuando se quiere crear una, en lugar de tener que crear todas las dependencias con todas sus dependencias
y así sucesivamente. Solo tenemos que marcar una
interfaz aquí y proporcionar los Dominios fueron para
todos esos métodos, ¿
verdad? Y ya terminaste. No tienes que ir en las dependencias de
la implementación del servicio de
usuario
en todas esas cosas. Sólo tienes que
burlarte de esa interfaz. Y eso es todo, ¿verdad? También prueba con una
prueba unitaria para ver cómo funciona. Vas a ver
una gran diferencia en
cuanto a la forma en que
implementas las pruebas. Bien, así que con eso,
saltemos a la siguiente
conferencia donde vamos a llamar a un servicio externo desde nuestra aplicación Spring
Boot.
7. Agregar configs en application.yaml: Bienvenida de nuevo. En esta conferencia
vamos a remodelar un poco esta implementación de servicio de
tiempo en particular, como puedes ver aquí, estamos usando el útero para hacer
una solicitud get a esta API de tiempo mundial para
obtener la actual tiempo. Pero ya sabes, este punto final
podría cambiar con el tiempo. Es posible que tengas que usar una API
diferente o que tengas múltiples endpoints en
tu aplicación y quieras administrarlos
desde un solo lugar. Entonces, en lugar de
buscarlos en todo tipo de clases, suele ser mejor tener un flujo de trabajo de configuración donde puedas almacenar todas tus constantes y detalles de tu
aplicación que puedan ser, que se debe administrar
desde un solo lugar en un archivo de
configuración dedicado. Spring Boot tiene este mecanismo de
configuración que es muy simple de usar, y se integra muy bien en el marco de
inyección de dependencia del mismo. Entonces vamos a
usarlo ahora mismo. Entonces antes que nada, vamos
a ir a la clase principal. Vamos a agregar
esta anotación habilitar propiedades de configuración. Esto es necesario porque
vamos a usar una anotación de
configuración dedicada que es realmente útil, que es obligatoria para cualquier archivo de
configuración. Así que vamos a crear un
nuevo paquete llamado config. Y aquí mismo
lo vamos a llamar tiempo API configurar
esta clase. Vamos a anotar
con la anotación Configuration
, que básicamente la hace disponible en el sistema de
inyección de dependencias de Spring Boot, pero también, pero también le dice a
Spring framework que esta clase se debe utilizar para
almacenar datos de configuración. También vamos a
agregar una nueva anotación llamada propiedades de configuración. Y vamos a
actualizar esto en un segundo con un parámetro
dentro de esta clase. Vamos a tener nuestros campos, los cuales queremos tomar
del archivo de configuración. En este caso, queremos
obtener el punto final. Entonces básicamente este queremos almacenar en nuestro archivo de
configuración
y también en el continente, porque es posible que queramos cambiar la
configuración interna del continente de manera basada. Vamos a decir cadena
privada, endpoint y también continentes. Y vamos a crear getters y setters
para esos dos campos. ¿Y dónde vamos a
almacenar el archivo de configuración? Vamos a
entrar en el
directorio de recursos y
vamos a crear un nuevo archivo aquí llamado
aplicación punto YAML, primavera con nariz a Logan
en esta ubicación recursos, justo en los
recursos directorio. Y buscará esta
aplicación yaml archivo. Si esto está presente, buscará en su interior configuraciones. Así que en este
archivo de configuración voy a decir api punto punto punto punto punto punto final de la API. Y aquí mismo
voy a pegar el punto final de nuestra aplicación, que es esta, y alertar también pegas aquí el continente, en este caso Europa. Por lo que tener esta
configuración aquí nos
permitirá almacenar los
datos en un solo lugar. Ahora, en este tiempo, tal vez configúreme en las propiedades de
configuración. Vamos a establecer un prefijo
para nuestra configuración. Ahora un prefijo para
nuestra configuración es básicamente lo que
como dice el nombre, el prefijo bajo el cual
nuestra configuración para la aplicación
debería estar ubicada en el archivo yaml de la aplicación. Entonces en este caso, el valor
para nuestro prefijo debería ser API, ya que bajo esta clave API, tenemos esos dos
campos que
queremos almacenar en la clase
time config. En otras palabras, esto nos
permite tener todo tipo de
configuraciones jerárquicas, ¿verdad? Y dependiendo del prefijo, puedes seleccionar qué área de la configuración quieres
almacenar en tu clase, ¿verdad? Porque es posible que definitivamente
no quieras tener una clase grande con todas las configuraciones
en
la aplicación yaml, ¿verdad? Bien, así que una vez que tengamos
esta clase creada, vamos a usar en la implementación del servicio de tiempo. Básicamente vamos a
inyectarlo ¿verdad? De la misma manera que lo hicimos con los otros servicios que
agregamos en el constructor. marco de inyección de dependencia se
encargó de su inicialización. Así que vamos a decir
constructor time API config donde quieres almacenar eso en nuestro campo,
y eso es todo. Ahora vamos
a usarlo, ¿verdad? Así que vamos a decir API de tiempo, punto de
configuración, GET endpoint. Vamos a concatenar
esto con get continent y luego con la zona horaria que obtenemos del parámetro. También vamos a
hacer esto un
poco más corto en esa línea. Bien, entonces el punto final, si echamos un vistazo
un poco documentación y en slash, y luego tenemos el continente, que es Europa, y
luego obtenemos una zona horaria. Entonces necesitamos también una baraja
extra aquí porque la zona horaria
es una cadena directa. Entonces necesitamos agregar un barco de
esclavos extra. Eso debería ser. Pongamos aquí un punto de interrupción para ver si esto realmente funciona. Bien, así que ahora vamos
a hacer una solicitud para agregar un usuario y vamos
a echar un vistazo esta vez llamado API config. Y podemos ver que
conseguimos nuestros valores poblados correctamente
en esta clase. Y si hacemos la solicitud, debería funcionar como
esperamos, ¿verdad? Entonces llegamos a cero para aceptar
si lo recuperamos sí. Deberíamos funcionar como esperamos. Sí, esa es
prácticamente la forma en que
podemos jugar con
las clases de configuración en Spring, pero también podemos cambiar algunas
configuraciones predeterminadas que son leídas por trampolín, por ejemplo, el puerto en que nuestra
aplicación está ejecutando, en este caso, TDAH. Si queremos usar
un puerto diferente, podemos decir fácilmente el puerto
del servidor 9019. Y cuando nos dimos cuenta de
la aplicación, Spring Boot leerá esa configuración y
cambiará el puerto en
consecuencia, ¿verdad? Como puede ver, el cambio entró en vigor inmediatamente
en la siguiente ejecución. Por supuesto, la
documentación cubre todas las configuraciones disponibles
que podemos agregar aquí. También puedes hacer lo
mismo usando el archivo de propiedades de
la aplicación. Entonces, si estás buscando en
Internet y estás golpeando este archivo de configuración es
más o menos lo mismo, excepto que tiene una forma más corta de especificar la aplicación de
configuraciones. Yaml trabaja
más o menos de la misma manera. Entonces con eso, saltemos
a la siguiente conferencia.
8. Llamar a servicios externos a través de HTTP: Bienvenido de nuevo. Entonces, generalmente en un servicio web, o interactúas con una
base de datos para tomar algunos datos, procesarlos y
luego entregarlos a tus clientes. O interactúas con un servicio
diferente
para obtener algunos datos
o agregar algunos datos a ese servicio para ejecutar algún tipo de flujo de trabajo de negocios que
se supone que debe
hacer tu aplicación en nuestra aplicación. Digamos que cada vez que
agregamos un usuario a nuestro mapa, también
queremos almacenar
el tiempo de creación en UTC cuando ese usuario fue creado para el
tiempo de creación de ese usuario. Y en lugar de hacer
esto llamando a los métodos nativos que
tenemos en la API Java, queremos usar una
API externa juntos desde el tiempo para dar cuenta de los
sesgos de tiempo o cosas así. Sólo vamos a hacer eso también por el bien del ejemplo sobre cómo hacer una
llamada HTTP a una API externa. Vamos a hacer eso. Entonces la API a la que
vamos a ir a llamar se llama API de hora mundial. Es una muy sencilla
. Solo tienes que hacer una solicitud
a esta URL con la zona horaria y le devuelves un ancho
de carga JSON algunas veces, entonces vamos
a usar esta. Así que preparemos
un poco toda la aplicación para eso. Vamos a crear un nuevo
servicio al que vamos
a llamar servicio de tiempo. No necesariamente el mejor nombre, pero es el que
vamos a usar. Entonces vamos a
anotarlo con
la anotación de servicio y también
vamos a cambiar
eso a tiempo de
implementación del servicio, ¿verdad? Y vamos a usar la interfaz de servicio de
tiempo. Entonces, ¿qué métodos
necesitamos usar para poder devolver la hora
real, verdad? Obtener la hora actual, podemos
decir obtener la hora actual. Y aquí podemos proporcionar
alguna zona horaria, ¿verdad? Que puede ser algo
así como la ciudad en Europa o en otras
áreas de lo global, queremos conseguir el tiempo. Entonces volviendo a
la implementación, podemos implementar los métodos. Justo aquí. Podemos, en realidad podemos
hacer el núcleo, pero ahora usemos ese servicio en nuestra implementación
de servicios. Entonces en el constructor
podemos solicitar
al framework de inyección de dependencias una instancia del
tiempo de servicio de tiempo, encuestas de tiempo de
servicio que también
podemos almacenar
como campo privado, que también puede ser definitivo
por cierto, ¿verdad? Lo mismo con este
porque queremos
crear las instancias de una
sola vez, ¿verdad? Entonces conseguimos el servicio, el servicio de tiempo aquí, y solo
lo vamos a usar en el método Add User. Lo que por supuesto necesitamos un
campo en el modelo de usuario donde queremos almacenar
el tipo de creación. Creación. También se necesita el setter y
getter para este campo. Y lo vamos a
crear usando la funcionalidad de
idea inteligente. Entonces conseguimos un getter, y también queríamos un setter
para ese campo, ¿verdad? Entonces vamos a mover esos dos métodos
abajo después de ser deconstructivos. Entonces ahora tenemos un lugar
en nuestro modelo donde queremos poner este tiempo de
creación. Solo tenemos que decir
time service dot en
realidad en el modelo de
usuario, ¿verdad? Cuando dices punto de usuario,
establece el tiempo de creación. Y aquí tenemos que decir
tiempo servicio punto obtener tiempo
actual de,
digamos Amsterdam. Este debería ser un momento. Entonces digamos que es en
Europa por defecto. Ámsterdam es la
ciudad que queremos. Ahora, por supuesto,
esto, esta zona horaria se
puede obtener de
un servicio externo, servicios de
co-ubicación,
que detecta la ubicación
en función de la IP del cliente. Entonces puedes ampliar esto aún más para obtener una funcionalidad cada vez más
compleja. Pero en este caso sólo
vamos a dejarlo como está. La pregunta principal aquí sería, ¿cómo obtenemos el tiempo? ¿Cómo llamamos a esa API HTTP? Entonces para eso, vamos a usar un cliente HTTP que
se llama union rest. En Java, podemos
llegar a ser clientes. También tenemos una versión incorporada, pero esta es la forma
más fácil que conozco de hacer una solicitud HTTP desde una
aplicación a una API externa. Así que solo vamos a
importar la unidad de dependencia, mientras que Java, la
vamos a poner en el archivo Gradle
acumulado y presionar Sync. ver si eso es lo correcto. 11311. Parece genial. Detectado que hay una versión más reciente de
esa dependencia. Ese es el indicado. Entonces en nuestro servicio en nuestro tiempo, cuando queremos obtener
la hora actual, podemos decir algo como esto. Punto de descanso de unión,
consíganos una URL aquí. Y la URL es la
que tenemos aquí mismo. Pero claro, necesita
incluir esta zona horaria. Entonces podemos decir como Jason. Entonces, lo que esto hace es hacer la solicitud y recuperar
la respuesta. Ahora como Jason devuelve una
respuesta HTTP del nodo Jason, que es un tipo de datos más
primitivo. Realmente no queremos hacer esto. También queremos convertir
esto en un modelo. Entonces veamos si tenemos
otras opciones para esto, para este cliente HTTP. Entonces digamos como objeto, ¿verdad? Aquí tenemos esto como objeto. También tenemos la versión asíncrona. Entonces cuando decimos como objeto, necesitamos proporcionar
aquí una clase que tenga este formato de la
respuesta que
esperamos de la API, ¿verdad? Entonces esto es algo que
necesitamos crear dentro y fuera. Entonces en los modelos
podemos decir tiempo. O la respuesta de la API de tiempo del temporizador. Este puede ser un nombre para nuestra clase y tenemos
dos opciones, ¿verdad? En, al definir esta clase, podemos crear un campo para cada par de valores clave
que tenemos aquí mismo. Pero porque no vamos
a usar todos esos campos, en cambio vamos
a usar sólo éste. No necesariamente tenemos
que crearlos todos. Sólo podemos crear
éste. Entonces UTC fecha hora, vamos a decir
cadena privada UTC fecha hora, el nombre debe coincidir. Podemos sumar constructores, ¿verdad? Y también getter y
setter para ese campo. Y vamos a mover el
constructor un poco arriba aquí mismo en este lugar de nivel de
clase, vamos a decir json,
ignore, ignore, ignore
propiedades, ¿verdad? Entonces, lo que
hace esta anotación es ignorar todas las propiedades
que no
estamos aquí como
campos en nuestra clase. En este tiempo, simplemente
extraemos lo que necesitamos
de esa carga útil. Entonces teniendo este modelo, podemos usarlo aquí mismo. Y se puede ver implementación de
servicio de tiempo. Podemos ver tiempo de
respuesta API a clase. Y podemos tenerlo aquí mismo. Obtener cuerpo, bien. No debemos olvidar este
cuerpo porque como objeto devuelve una
respuesta HTTP de tu tipo. Así que necesitamos usar
get body para obtener el derecho obtener el objeto de respuesta
real. Una vez que tengamos esta respuesta, podemos decir response dot get
you to datetime, right, extrayendo el campo
de nuestra clase. Bien, entonces veamos qué
hemos hecho hasta ahora, ¿verdad? Entonces usamos este servicio para extraer los dos juntos
tiempo de esta API externa, y colocamos ese tiempo en un nuevo campo en nuestra clase
UserModel. Ahora bien, claro que
necesitamos ver si esto funciona. Así que vamos a llegar a ese punto de interrupción
y reiniciemos nuestra aplicación. Solo voy a
agregar también un punto de interrupción dentro nuestra
implementación de servicio de tiempo para ver si el carbón se ha
hecho correctamente. Entonces voy a volver a
agregar este usuario y puedo ver esta
respuesta, ¿verdad? Y ese es el indicado. Entonces puedo ver algunos datos aquí, lo que significa que
obtuve la respuesta correctamente de
esta API externa. Si quieres
depurar más cosas, también
puedes eliminar
ese cuerpo todavía y usar esta respuesta HTTP de respuesta de
tiempo API, ¿verdad? Y luego decir respuesta punto, obtener cuerpo, obtener UTC, fecha, hora. Porque en esta respuesta HTTP, se pueden
ver más cosas como el estado HTTP o si
hay algún búfer de datos, todo tipo de detalles se pueden
ver en este objeto, ¿verdad? Entonces voy a darle otra vez a eso. Y voy a ver esta respuesta
HTTP
volviendo bien. Para que veas que
obtenemos el código de estado 200. Se puede ver que no
tenemos ningún error. Puedes ver los encabezados que
se recibieron de esta API. Podemos ver aquí todas ellas. Y también podemos ver el cuerpo. El cuerpo tiene esto, este objeto con nuestro tipo de datos, derecha, golpea F9 para
continuar con la ejecución. Y eso es todo, ¿verdad? Llegamos a cero para aceptarlo. Ahora bien, si recuperamos al usuario, también deberíamos ver este tiempo de
creación porque estos get flow realmente devuelve todo
el objeto y
lo muestra en la respuesta HTTP. Así que eso se
trata prácticamente de llamar a un servicio externo desde tu
aplicación en Spring Boot. Esa es una forma muy interesante de conectarse con
otros servicios. Y en la próxima
conferencia vamos a trabajar un poco en esta
implementación del servicio de tiempo para
que sea un poco
más configurable. Entonces con eso, saltemos
a la siguiente conferencia.
9. Configuración de MySQL con Docker: Hola a todos y bienvenidos de nuevo. En esta conferencia,
vamos a ver cómo
podemos conectarnos a una base de datos desde
una aplicación Spring Boot. Porque como mencioné
en la conferencia de servicios, el microservicio puede
conectarse a un servicio externo para tomar
algunos datos o enviar algunos datos, o puede conectarse a
una base de datos para exactamente lo mismo cosa, ¿verdad? Así que de alguna manera necesitas
una forma o un lugar para almacenar tu información y recuperarla de
tu aplicación. Y claro, traer madera
tiene una serie de mecanismos que nos permiten hacerlo de
una manera más fácil en comparación con, digamos que lo estás
haciendo por nuestra cuenta. Y también es
importante ver esto en el contexto de tener
múltiples sabores y
modelos de bases de datos y esquemas de
modelado de datos. Entonces vamos a mirar
a este ejercicio desde esas tierras de este complejo,
digamos, ecosistema de
almacenamiento de datos que tenemos en la
industria a partir de ahora. Entonces básicamente lo que vamos
a hacer en esta conferencia es reemplazar este mapa de usuario
con mi tabla de secuela, que en realidad tendrá un
esquema con muy similar al que tenemos en
este modelo de usuario, ¿verdad? Así que prácticamente todos
los mismos campos con, digamos con un ID
que servirá como identificador para
un registro en la base de datos como clave primaria. Entonces básicamente esta conferencia
tendrá dos partes. El primero será aquel en el
que vamos a crear una base de datos y configurarla
para crear la tabla real. La segunda parte
será modificar realmente nuestra aplicación Spring Boot para interactuar con la base de datos. Entonces comencemos con
el primer paso, ¿no? Voy a abrir mi
terminal y voy a usar Docker para ejecutar
un contenedor MySQL. Ahora claro, Docker no es un requisito previo para este curso. No espero que
sepas cómo es. Entonces por esa razón, voy a hacer una introducción
muy pequeña a esta tecnología en particular y voy a explicar todos los comandos que estoy
ejecutando paso a paso. Así que en realidad puede ser más fácil
para ti seguir adelante. En primer lugar, el tiempo de ejecución
del contenedor Docker. De hecho, puedes ir
aquí mismo en docs.docker.com. Y en realidad puedes encontrar muchos detalles sobre Docker
como la tecnología. En pocas palabras, docker
es una tecnología que nos
permite ejecutar contenedores. Y el contenedor es básicamente una máquina virtual
ligera que no requiere
un hipervisor, como VirtualBox o
VMware o Hyper-V. Así que básicamente puedes ejecutar
un contenedor usando más oscuro si instalas el Docker Engine en tu sistema operativo, y por supuesto si
ejecutas algunos comandos. Entonces por ejemplo queremos ejecutar MIC llamado contenedor
en esta máquina, ya
tengo Docker
instalado aquí para Mac. Entonces para poder ejecutar
un contenedor MySQL, tengo que decir
Docker run menos E, mi contraseña de raíz cuadrada, y luego un mapeo de puertos, y luego mi imagen secuela
seguida de version. Entonces veamos qué hace realmente este
comando. Docker run significa que quiero
ejecutar un contenedor
usando más oscuro, ¿verdad? Entonces menos e dice, quiero crear
esta
variable de entorno y ponerla a
disposición en el contenedor. La variable de entorno es
básicamente solo un par
de datos clave-valor que es accesible
en un entorno específico, ya sea en el
programa actual o en un contenedor, generalmente a
nivel de sistema, ¿verdad? Esa es la razón por la que se le llama básicamente variable de entorno. Entonces en este caso quiero
establecer la contraseña root para el usuario root porque para
poder iniciar sesión en mi secuela, necesitamos tener la
contraseña para el usuario root. Y en este caso, el valor para la contraseña
será simplemente test. Y luego menos p significa que quiero hacer
un mapeo de puertos. Un puerto es básicamente
un identificador para una aplicación en el contexto de un sistema más grande con
múltiples procesos. Por lo que un sistema operativo
tiene una serie de puertos a los que puedes conectarte
a través de la red. Y cada puerto básicamente
identifica una aplicación. Y la aplicación puede recibir conexiones
en ese puerto y manejarlas y
recuperar respuestas y así sucesivamente, ¿verdad? Entonces en este caso quiero decir, quiero mapear este tratado portuario
O6 desde mi máquina local. Desde la máquina cuando estoy
ejecutando este comando, que también se conoce
como el host hasta el puerto 3306 en el contenedor. Ahora, en el contenedor de este
puerto, mi proceso secreto en realidad
se eleva. Por esa razón. Elegí este retrato, el O6 justo en el contenedor. Entonces en un eje, el proceso a través de este puerto y el puerto host puede
ser algo diferente. Entonces puedo tener a un valor
diferente aquí. Y desde nuestra aplicación Spring
Boot, cuando quiero conectarme
a esta base de datos MySQL, tengo que especificar este puerto
host que yo, que me siento aquí justo. Ahora por simplicidad, simplemente puedo decir que quiero
usar el mismo puerto, que es el predeterminado
para mi escuela, para que no nos
encontremos con otros problemas. O sea, simplemente se puede ver
si el puerto no está bien porque simplemente fallará al
conectarse a la base de datos. Para que puedas
cambiarlo inmediatamente a la correcta. El siguiente argumento es menos d, y menos d significa
ellos en contenedor. Entonces cuando ejecute este comando, la terminal no esperará a que
el contenedor sea
asesinado o terminado. Simplemente arrancará un
contenedor en el fondo. Y el argumento final de este
largo comando es mi secuela, seguida de calcio,
seguida de última. Mi secuela es
básicamente el nombre de la imagen que queremos ejecutar. Las imágenes de los contenedores las puedes encontrar si estás
buscando mi secuela Docker image. Y puedes ver este
sitio web, Docker Hub, donde tienes básicamente
todas las imágenes que puedes obtener
públicamente, ¿verdad? Entonces van subiendo es básicamente un repositorio público de imágenes. Y esta es
la línea oficial. Entonces, si eres, por ejemplo,
si estás ejecutando este comando docker,
tira de mi secuela. Empezará a descargar esta imagen en su sistema
local a la derecha, desde el repositorio remoto. Ya tengo esta imagen. Descárgalo, así no
tengo que volver a descargarlo. Ahora bien, lo último que
realmente significa aquí es la versión de imagen porque
la imagen puede tener múltiples etiquetas o
derecho, o versiones. Entonces actualmente estoy
usando lo último, pero también puedes usar una versión
anterior si
quieres 8031 o cualquiera,
cualquier otra. Entonces ejecutemos este comando. Entonces como pueden ver, nos llegó este error que dice que el
puerto ya está asignado, probablemente porque tengo
este contenedor funcionando, digamos que docker ps nos dice qué contenedores se están ejecutando
actualmente. Entonces por ejemplo I. En realidad
puedo decir que Docker mata este contenedor y
este comando simplemente destruirá el contenedor en
ejecución, que fue creado
anteriormente por mí. Entonces si ejecuto docker
ps ahora dice
que no tengo ningún
contenedor funcionando. Y si ejecuto el comando que volverá a iniciar un
contenedor, que por supuesto sería
otro contenedor. En este caso, me
devuelvo este ID muy grande, y este es el ID del
contenedor es básicamente debería ser un ID único que
Docker genera para nosotros. Ahora bien, si dirijo la Corp, sí, puedo ver que el
contenedor está funcionando. Tengo este ID aquí
que identifica que el contenedor es básicamente una versión
más corta de este. Entonces puedo ver la imagen que
usa el contenedor, seguida del primer
comando que se está
ejecutando cuando se inicia el
contenedor. Y esto está dentro de
la imagen misma, así que no podemos controlar
esto y el bosque. Otra
información importante alrededor este contenedor es el
estado creado y así sucesivamente. También aquí también se
muestran los
mapas de puertos que vimos anteriormente. Entonces tenemos este
contenedor funcionando. Ahora vamos a iniciar sesión en este
contenedor para que podamos configurar la base de datos MySQL. Entonces para iniciar sesión en este contenedor, solo
tenemos que decir
docker exec menos IT, seguido del
ID del contenedor, seguido de batch. Entonces i t significa terminal
interactivo. Quiero ejecutar este comando. Exacto significa que quiero ejecutar este comando en
modo interactivo en este contenedor. Y el comando es
simplemente Bash que
quiero obtener acceso shell
a estos contenedores. Entonces, si ejecuto este comando, puedo ver que el
shell realmente cambió. Y cambió porque
ahora básicamente estoy ejecutando comandos en
el contenedor, ¿verdad? Entonces ya no estoy en el anfitrión
local. Estoy en el sistema de archivos contenedor y en el
sistema contenedor básicamente por ejemplo si estoy ejecutando el comando ls, puedo ver que tengo un conjunto
diferente de archivos, correcto, comparado con el
que obtuve antes. Ahora claro, lo
que me interesa
aquí mismo en este contenedor
es acceder al laboratorio. Entonces para hacer eso, tengo que
iniciar sesión en mi pantalla. Entonces tengo que decir
mi secuela menos U, que significa User route, right surrounded login with a root user menos
p y luego Enter, ahora tengo que introducir la
contraseña para el usuario root, que en realidad es
esta que proporcioné a través de esta variable de
entorno. Entonces puedo decir prueba aquí, acabo de escribir test
y luego Enter. Y eso lo puedo ver.
Y ahora estoy conectado
a la base de datos de mi secuela. Entonces lo primero que
tengo que hacer aquí, porque esta es una base de datos
fresca. Tengo que decir crear prueba de
base de datos. Quiero crear una
nueva base de datos que se llame test y ese comando, ahora tengo que usar esta base de datos. Entonces tengo que decir prueba de uso. Y ahora necesito crear una
tabla dentro de esta base de datos. Entonces ya tengo consulta que me permite
crear esta base de datos, cual es esta, ¿verdad? Entonces integro esta entidad de usuario de
tabla, que tiene esta clave primaria. Y lo hice eso es
auto incrementado. Y luego obtuve los
campos que ya forman parte del modelo de usuario en nuestra
aplicación Spring Boot, correcto, así que voy a
copiar este comando, pegarlo aquí, y luego la consulta se ejecutó
con éxito. Quiero obtener algunos datos
de esa nueva tabla. Por supuesto que voy
a obtener cero resultados, pero sólo para ver si la tabla fue creada correctamente, ¿verdad? Tengo un set vacío. Entonces ahora la base de datos
está básicamente establecida. No hay otras cosas que
hacer aquí le dará al usuario la aplicación
Spring Boot para que realmente
agregue datos en esa base de datos.
10. Configuración de nuestra aplicación de iniciación de primavera para que funcione con MySQL: Entonces cambiemos a idea
inteligente para comenzar a configurar
estas premultiplicaciones. Bien, así que
lo primero que tenemos que hacer es, por supuesto, importar
algunas dependencias porque no tenemos soporte
incorporado para el acceso a datos en la dependencia
web de Spring Boot starter. Entonces necesitamos agregar las
siguientes dos dependencias. Por el momento, vamos
a ver si necesitamos otros. En el camino. Vamos a buscar
en la web Spring Boot Data,
JPA, Maven Central. Así que JPA significa
Java persistencia API. Y Spring Boot tiene una dependencia
dedicada que se ocupa de
cualquier abstracción o son en realidad
la API completa que nos
permite acceder a
los datos usando Spring Boot. Vamos a copiar
esta dependencia, Spring Boot starter Data JPA. Y luego vamos
a buscar también conector
MySQL,
Java, Maven Central. Esto es básicamente una
dependencia que nos permite
conectarnos a mi base de datos SQL. Básicamente necesitas
tener un conector para cada base de datos a la que
quieras conectarte. Y deberían estar en
el mismo repositorio. Así que sigue encendido, en mi central. Pero ésta es para
mi secuela y necesitamos , por supuesto, importante. Voy a golpear gradle
sync usando el atajo. Y claro que íbamos
a esperar a que Gradle
recogiera las dependencias
para poder
empezar a trabajar en el proyecto. Bien, así que ahora tenemos
las dependencias en, tenemos que hacer los
siguientes cambios. Entonces vamos a crear un nuevo paquete al que
vamos a llamar data. Entonces este paquete de datos, voy a crear una clase a la que voy
a llamar entidad de usuario. Y esta clase es la
que vamos a ir, que vamos
a utilizar para
enviar datos a la base de datos
y recuperarlos. Entonces te preguntarás, ¿por qué no usamos la clase
UserModel para esto? Bueno, porque esta clase forma
parte del modelo de dominio que utilizamos para la comunicación
con el controlador resto. O vi esto, este esquema
es el que
estamos obteniendo del usuario
directamente usando Postman. Entonces necesitamos desacoplar
esos dos modelos, ¿verdad? Porque es posible que no
necesariamente tengamos exactamente
la misma estructura
en una aplicación real. Desde el frente y
desde el lado del cliente, hasta
la base de datos mujeres, podemos tener un
modelo diferente justo en este piso. Entonces por esa razón estoy
creando una diferente, que básicamente va a
ser muy similar a esta. Así que básicamente voy a copiarlo y pegarlo aquí mismo. Voy a decir entidad de usuario. Este es un
poco diferente
porque necesita implementar una interfaz
serializable, ¿verdad? En la vida real. Entonces, la razón por la que necesita
implementar serializable es porque esta clase se
pasará a la base de datos, ¿verdad? Necesita que coincida con las columnas sobre la
mesa que creamos. Entonces, como probablemente
viste aquí mismo, obtuvimos FirstName, LastName, ID de
membresía, tiempo de creación. Entonces esos campos son en realidad
esos, pero claro, escritos con el subrayado
entre las palabras, ¿verdad? Entonces básicamente necesitan
igualar los que
tenemos en la tabla. Y también necesitamos
anotar esta clase con una
anotación muy importante que se llama entidad, ¿verdad? Esta clase, que viene
para Java, API de persistencia, básicamente nos dice
que esta clase necesita ser emparejada con tabla en nuestra,
en nuestra base de datos, ¿verdad? También podemos anotar campos con todo tipo de anotaciones
relacionadas con la clase de entidad. Así podremos personalizar
aún más esta clase si tenemos un escenario
más complejo. Pero para este curso
no vamos a entrar en demasiados detalles sobre cómo
configurar esta clase. Solo vamos a mantenerlo
simple por el momento para ver
cómo las cosas se conectan de extremo a extremo. Y también puedes explorar más aspectos en esta área
si te interesa. Entonces obtuvimos la clase de entidad. El segundo aspecto que
necesitamos crear es el repositorio de usuarios. Ahora el repositorio de usuarios es
básicamente una interfaz que extiende el repositorio de crédito de la entidad de usuario
seguido de una cadena. Entonces, ¿por qué tenemos aquí, tenemos una interfaz
llamada repositorio de usuarios, que se anota
con un repositorio en que realmente se extiende el repositorio de
crud. Esta interfaz que
forma parte de Spring Boot, es básicamente la abstracción
principal de un acceso a datos
que proporciona operaciones de creación, lectura, actualización y
eliminación. Y necesitamos también proporcionar
aquí los objetos sobre los que queremos ejecutar
esas operaciones con el curso de base de datos. Y también la clave primaria
que queremos usar cuando ejecutamos las operaciones
en esas entidades, ¿verdad? Entonces como puedes ver en esta
interfaz, tenemos guardar, guardar todo multado por
el existe por ID. Entonces las operaciones que
podemos ejecutar directamente. Así que ahora que tenemos aquí este repositorio de
usuarios, hecho
podemos
usarlo directamente en nuestra implementación de servicio al usuario. Entonces podemos inyectarlo aquí mismo, repositorio de
usuarios, podemos almacenarlo como un campo y también
podemos usarlo. ejemplo, en el getUser, podemos decir return user
repository dot find by ID. Ahora necesitamos proporcionar una identificación. Entonces agregamos aquí este hallazgo por
primer nombre metal, que básicamente
nos permite hacer una consulta en nuestra base de datos usando
el firstName y right, y recuperando una entidad de usuario. Ahora primero, tenemos este pequeño
problema que necesitamos para convertir la
entidad de usuario en modelo de usuario. Y para eso, vamos a crear un mapador
escribiendo una clase que
sobre todo que está
diseñada para convertir de entidad de usuario a modelo de
usuario y de vuelta. Pero antes de entrar en esa parte, también
vamos a usar el repositorio de usuarios
para agregar algunos datos. Entonces, para agregar datos en la base de datos, necesitamos usar el método save. Y en el método save
necesitamos proporcionar, por
supuesto, una entidad de usuario, ¿verdad? Lo vamos a
proporcionar de inmediato una vez que tengamos creados los
mapeadores. Pero vamos a implementar también una
eliminar los métodos de usuario. Entonces vamos a decir repositorio de
usuarios eliminar por nombre de usuario, ¿verdad? Entonces necesitamos otra
consulta aquí mismo. Entonces para ello, también necesitamos
crear un nuevo método, eliminar por nombre de pila. Entonces vamos a decir aquí, eliminar por nombre,
agregar el nombre de usuario. Y también necesitamos
eliminar estos mapas de usuario. En realidad ya no lo
necesitamos. Y también vamos a crear
esa clase de mapeadores que mencioné anteriormente. Así que vamos a crear un
nuevo paquete llamado Mappers. Entonces un mapeador es
básicamente solo una clase, digamos
mapeador de entidad de usuario que nos permite convertir de un
tipo a otro. Así que en realidad vamos a crear una interfaz
llamada primero entidad mapper. Y esta interfaz,
digamos tiene que generar parámetros y
tiene dos métodos. Así que el mapeador NFet
básicamente nos permite
convertir de este
tipo a este tipo. Entonces vamos a regresar, dices mapa, y luego vamos a tomar entidad
como una t, como parámetro. Y también proporcionamos la operación inversa
donde convertimos, donde obtenemos una t
de una escribes. Entonces digamos que esta es la abstracción que
vamos a usar. Y el mapeador de entidad de usuario
implementará el mapador de entidad de usuario y modelo de usuario. ¿Bien? Entonces, si implementamos
esos métodos, podemos ver que el primero nos
va a conseguir un modelo
de usuario de una entidad de usuario. El mapa inverso nos conseguirá una entidad de usuario a partir de un modelo de usuario. Entonces también vamos a hacer esta clase un componente, ¿verdad? Porque lo usamos como herramienta. En este caso,
podemos simplemente
devolver modelo de usuario de usuario, en realidad entidad punto firstName, lastName, ID de membresía, y tiempo de
creación, por supuesto, con un nuevo y
por supuesto esto es un un poco
redundante en este caso, pero en un escenario real
estás, vas a tener
esos modelos a la deriva. Entonces necesitas agregar algunos
cambios aquí mismo, ¿verdad? Alguna clase no tendrá
un parámetro específico, la otra lo tendrá. Entonces necesitas hacer algunas conversiones aquí mismo para hacer algo de sanitización
a veces. Entonces estoy haciendo esto más como
un ejercicio para
saber que esto puede y
sucederá en un escenario real. Ahora con este mapeador de
entidades de usuario, vamos a inyectarlo en la
implementación del servicio de usuario. Pero claro que vamos
a usar la interfaz,
bien, para tener las cosas desacopladas. Entonces entity mapper, donde hay que usar el mapeador de entidad, que es éste digamos usuario,
digamos entidad mapper para ser, para estar seguros lo conseguimos como campo. Y justo aquí donde
encontramos por nombre de pila, ¿verdad? Entonces cuando recuperemos la entidad de
usuario, vamos a decir
map porque
tenemos la entidad y queremos
recuperar el modelo de usuario. ¿Bien? Entonces esto es lo que queremos. Ahora, cuando queremos
guardar un uso de una entidad, lo que quiere decir mapa de entidad
mapeado inverso de puntos. Y vamos a
pasar al usuario, ¿no? Pasamos el modelo de usuario, el mapa inverso
recupera una entidad de usuario que se utiliza para
la misma operación. Entonces esta es básicamente
la forma en que lo haríamos. Por supuesto, no
tenemos manejo de errores, no
tenemos
manejo de excepciones en este código. Básicamente es lo más simple
posible para que puedas
hacerte la idea principal. También podemos hacer esos definitivos. Y lo último
que realmente necesitamos en esta aplicación para
poder conectarnos a la base de datos es agregar aquí en la aplicación
yaml configuración para la base de datos, ¿verdad? Entonces para ello, así que básicamente endpoints el puerto y esta configuración
es la siguiente, ¿verdad? Entonces yo solo, acabo de pegar esta
configuración de un archivo. El restaurado anteriormente
es básicamente una configuración de fuente de datos de primavera
donde pasamos la URL, derecha, que incluye
el punto final un puerto. Este es el
puerto anfitrión, muy importante. Entonces el primero en este
comando de aquí, ¿verdad? Entonces este, el
primero, el puerto host,
seguido del nombre de la base justo aquí tenemos el
nombre de usuario y contraseña. Entonces con esos detalles, podemos conectarnos a la base de datos. Por supuesto, hay otros
en
aplicaciones de grado de producción, es necesario
especificar
todo tipo de configuraciones de pool de conexión
y muchos otros detalles. Pero para mantener el ejemplo, esta es la
configuración mínima que necesitamos proporcionar aquí para poder
conectarnos a la base de datos. Así que vamos a ejecutar esta aplicación en modo de
depuración para ver si funciona. Lo más probable es que no lo haga
porque nunca funciona en el primer intento. Entonces como puedes ver aquí. No tenemos clase. Encontraron Java x, x xml. Excepción muy extraña, ¿verdad? Por lo general, cuando tenemos
una clase no encontrada, probablemente se rompa
una dependencia. Y en este caso básicamente estamos hablando de esta dependencia, J XB menos API. No estoy muy seguro de
cuál es el problema. Encontró eso en internet
como un problema común. Entonces vamos a agregarlo aquí
para ver cómo funciona, ¿verdad? Entonces ahora dice que
no tenemos ningún identificador
especificado para entidad. Entonces esto significa que
necesitamos agregar un identificador para
esa entidad de usuario. Identificador es básicamente un
campo anotado con el ID. Entonces en nuestro caso, tenemos que agregar esta anotación de
ID, por
supuesto, en la clave primaria. En nuestro caso, no
necesariamente queremos agregar, digamos, un ID entero
aquí mismo podría no ser útil. Digamos que podemos
probarlo FirstName y ver, y ver cómo funciona, ¿verdad? Entonces, como puedes ver, las
aplicaciones iniciaron. Ahora intentemos agregar un
usuario en nuestra aplicación. Entonces vamos a ir
aquí mismo en el metal seguro en el método Add User en Río para usar Postman para agregar
un usuario, ¿verdad? Veamos qué dice. Golpeamos F9, sin excepción, también
volvemos a cero. Entonces significa que no hay excepción de la aplicación, ¿verdad? Por lo que podemos golpear seleccionar
de la entidad de usuario. Podemos ver que el usuario
está en la base de datos, lo cual por supuesto es realmente genial. Es decir, logramos agregar
datos en nuestra base de datos. También agreguemos un usuario diferente. Entonces parece
funcionar como esperamos. Ahora intentemos
recuperar algunos datos. Entonces este,
parece que funciona. Si yo si estoy
buscando a Daniel, parece que funciona bastante bien, lo cual es realmente genial. O sea, sí,
también eliminemos a un usuario. Sí, entonces en estas operaciones
parece que tenemos un problema, parece que tenemos un error. Entonces lo que dice,
dice que ningún administrador de entidad
con transacción real disponible para el
hilo actual no puede procesar de
manera confiable para
eliminar carbón, ¿verdad? Entonces este error
nos dice que no tenemos esta anotación transaccional
en el método delete. Y este es un punto
clave muy importante sobre el que quería tocar base porque generalmente la
operación de eliminación es muy sensible. Quiero decir, en realidad puedes
ejecutarlo desde múltiples hilos, desde múltiples,
digamos flujos de ejecución porque puedes encontrarte con problemas de
concurrencia. Así que
en realidad puedes tener problemas de inconsistencia, condiciones de carrera. Para resolverlos en Spring Boot, es necesario
usar esta anotación
transaccional, que básicamente nos dice que se todas las operaciones en este
método relacionadas por supuesto con ejecutarán
todas las operaciones en este
método relacionadas por supuesto con
el repositorio de usuarios una transacción que es básicamente una
operación atómica en la base de datos, que puede
tener éxito o fallar, pero no se puede
ejecutar parcial, ¿verdad? Entonces por esa razón, necesitamos
tener esta
anotación transaccional en nuestro método para que podamos tener la operación de eliminación
ejecutada correctamente escribir. Así que agreguemos también un nuevo usuario
para que podamos ver que funciona. Eliminé al usuario de mercados
para ver si esto funciona. Si borro, digamos
el usuario de Daniel, ¿verdad? Parece que tenemos 204,
bien, y el usuario es
eliminado de nuestra base de datos. Entonces así es como funciona. Voy a dejar que se solucione este problema con
las entidades de usuario. Entonces solo pruébalo, mira si puedes usar, puedes encontrar en la
documentación y anotación que
nos permitirá generar un ID. Entonces en otras palabras, puedes, puedes probarlo para agarrar
este campo ID aquí en la tabla para agregarlo como un campo solo entidad de usuario y
ver si funciona. Vea si podemos
generarlo automáticamente desde nuestra aplicación Spring Boot
y no desde la tabla. Entonces esta es básicamente
una forma en la que puedes jugar y cubrir las cosas. ver si funciona, a ver
si no funciona. Ver, investigar por qué.
Esta es la forma en que puedes, puedes aprender básicamente
todas esas cosas. Entonces esta es básicamente
una forma muy sencilla acceder
a una base de datos como una de extremo a extremo sin
demasiados aspectos complejos en ella. Como mencioné
inicialmente, debido a que este panorama de bases de datos y sabores es realmente enorme, posible
que termines encontrándote todo tipo de problemas
con dependencias, con versiones, con que no están presentes
como vimos anteriormente. Entonces espera que este flujo
no sea impecable, quiero no ser algo
fácil de lograr. Entonces con eso, saltaremos
a la siguiente conferencia.