Transcrições
1. Introdução: Olá a todos e bem-vindos
ao curso intensivo do Spring Boot. O melhor recurso on-line de que você precisa para aprender o Spring Boot do zero e se tornar um engenheiro de software
melhor. A estrutura Springboard é usada por muitas grandes empresas de tecnologia para construir suas
arquiteturas de microsserviços e sistemas de
back-end em grande escala, porque ajuda você a criar uma produção de
alto desempenho
avalie os aplicativos enquanto mantém sua base de
código escalável. Incorporar
nosso conjunto de habilidades
permitirá que você se torne
mais competitivo
no mercado de trabalho e é definitivamente
uma tecnologia necessária para dominar seu caminho para se tornar um
software de back-end sênior engenheiro. Neste, nosso curso, criaremos do
zero uma API rest usando Spring Boot que
se comunica com uma API externa via HTTP, mas também com um banco de dados MySQL
local para armazenar alguns dados do usuário. O objetivo deste curso é
mostrar como o Spring
Boot funciona em um aplicativo de ponta a ponta com a funcionalidade semelhante
a um microsserviço. E espero que isso lhe
dê aquele poderoso começo de sua jornada de
se tornar uma primavera com o mestre. Os únicos requisitos para
este curso são ter uma ideia
inteligente instalada, conhecimento
básico de Java
e, claro, um forte desejo de
aprender novas tecnologias. Então, com isso, vamos começar
a primeira aula
deste curso.
2. Por que o SpringBoot?: Olá a todos, bem-vindos de volta. Então, antes de
mergulharmos no código real, vamos entender por que precisamos aprender a estrutura
Spring Boot. Aqui estamos
no
site oficial da Spring Width. E se clicarmos na Visão geral, podemos ver várias vantagens
dessa estrutura que são realmente validadas
pela indústria. Quero dizer, eles são adicionados
aqui mesmo no site. Mas a popularidade
dessa estrutura realmente diz algo sobre se essas vantagens são
realmente
verdadeiras ou não, certo? Então, primeiro de tudo, sobre a popularidade, certo? Mas a razão pela qual é tão popular é
porque é muito flexível e permite que você crie aplicativos
de taxa de produção muito rápido. Veremos mais adiante
neste curso que Spring With é realmente
fácil de configurar, seja usando anotações
ou arquivos de configuração. E também é importante
mencionar o cenário de aplicativos em que o
Spring Boot pode ser usado. Podemos usá-lo para
construir microsserviços, o que é mais ou menos como a nova tendência atual. Praticamente qualquer grande empresa tem essa
arquitetura de microsserviços em alguma parte de sua
infraestrutura. E o Spring Boot tem , na verdade, suporte total
para esse Mosley. Se você usar o Spring Cloud e os recursos de nuvem que o
Spring Cloud realmente
oferece, mas, além disso, você também pode criar aplicativos
reativos
e aplicativos orientados a eventos. Portanto, ele se integra a
praticamente todas as coisas novas
que estão acontecendo por aí. Então, em outras palavras, se você
sabe como o Spring funciona, você tem
uma vantagem neste mundo da engenharia de
software a partir de hoje. Portanto, há vários
clipes e documentações na Internet que
você pode realmente seguir se quiser ter uma visão geral, ou Palm Springs realmente funciona, muitas pessoas estão
realmente usando. Portanto, há muita
documentação na Internet. E o principal papel
deste curso é permitir que você use o trampolim
muito rápido. Portanto, não vamos
mergulhar em todos os pequenos
detalhes do trampolim. Vamos começar imediatamente e
começar com as principais capacidades
de Springfield, certo? Vou supor
que você não pode ter nenhuma
programação orientada a objetos e como as coisas funcionam nesse espaço. Estou em classes, interfaces, métodos e coisas assim. Então, conhecimento básico de Java. E então vamos
construir sobre isso com os recursos do framework
Spring Boot.
3. Crie seu primeiro aplicativo de Spring-Boot: Então, chega de falar. Vamos ver um código, certo? Se você quiser criar seu
primeiro aplicativo Spring Boot, temos duas opções. A primeira é usar esse site do
Spring Initializer, que você pode acessar na
inicialização do Spring dot io. E este site permite que você
crie um aplicativo
Spring Boot pré-configurado. Você só precisa clicar,
selecionar seu projeto, seu idioma,
sua versão do Spring Boot e completar o grupo de artefatos
do nome do projeto e coisas assim, incluindo a versão Java. E ao clicar em Gerar, você verá
que o navegador
baixará um arquivo
com o projeto em
um projeto de ideia inteligente que contém um aplicativo Hello
World simples com trampolim pré-configurado. É claro que esse é o caminho mais fácil, mas não vamos
seguir esse caminho. Em vez disso,
começaremos com
um
projeto de ideia limpa e inteligente e
adicionaremos o que é necessário em termos de dependências de primavera para
ver como ele realmente funciona. Então, aqui eu tenho a ideia inteligente,
Community Edition. Vou clicar
em Novo projeto. Eu vou dizer curso
Spring Boot. Vou selecionar Java como uma linguagem maior como
sistema construído. Vou usar o Java 17. E aqui
vou dizer Java dot,
spring, spring dot course. Quero clicar em Criar
e vamos esperar que o Gradle seja atualizado para baixar todas as dependências
iniciais. E esse é nosso primeiro projeto. Agora vamos
voltar à web e
pesquisar a web inicial do Spring
Boot. Maven, Central. Central é, obviamente,
o principal repositório para dependências baseadas em JVM Vamos pesquisar.
Essa dependência é chamada Spring Boot starter web. Essa é
uma espécie de dependência pequena que inclui
praticamente tudo o precisamos para criar um aplicativo
Spring Boot muito básico. Vamos clicar
na versão mais recente e selecionar Gradle. E vamos
copiar isso diretamente em nosso arquivo de compilação do Gradle,
a seção de dependências. Vou colá-lo aqui
e depois clicar em uma atualização maior. E então podemos ver que ele
foi baixado corretamente. Agora vou voltar à classe principal e aqui mesmo
no nível
da classe e entrar no nível
da classe e entrar aplicativo
anotado com o Spring
Boot. Essa rotação
vem, é claro,
da estrutura Spring Boot que identifica o ponto de entrada para nosso aplicativo
Spring Boot. E no corpo
da classe principal, vamos dizer Spring
application dot run. E aqui
vamos fornecer o objeto principal da classe de pontos. Portanto, este é um, esse
é o identificador da classe principal onde a mola com
anotação está localizada. Em seguida,
forneceremos os argumentos que foram fornecidos
no método principal. Então, o que essa linha realmente
faz é começar, a estrutura real é basicamente
uma instrução de bloqueio. Portanto, o aplicativo, o processo, processo
JVM não sairão até que o aplicativo seja
encerrado ou até que seja encerrado, o processo seja encerrado de alguma
forma, certo? Qualquer aplicativo Spring, quero dizer, qualquer servidor web, na verdade deve ser executado
por muito tempo porque deve aceitar
conexões contínuas de clientes HTTP. Então, quando
clicarmos em executar, veremos
nos logs essa saída. Então você pode ver essa bela arte dizendo primavera e
também a versão primaveril. E nos registros,
podemos ver que obtivemos aqui os registros do servidor web
Tomcat. Podemos ver a porta na qual
o aplicativo está sendo executado e podemos ver que ele foi
iniciado com êxito. Em outras palavras, o
Tomcat é basicamente um servidor web que
vem com o Spring Boot. Então você também pode
instalá-lo de forma independente, certo? Ele é construído pela comunidade
Apache e é basicamente um servidor web
clássico, apenas aceita conexões, segue o protocolo HTTP
e tudo mais. A principal razão pela qual ele foi
incorporado à estrutura, acredito, é
porque é muito leve. Portanto, ele não consome muita memória e muitos, muitos recursos. E provavelmente esse foi o
motivo pelo qual ele foi escolhido para fazer parte da estrutura do
trampolim. Acredito que também podemos
alterá-lo, se você quiser, com Apache, o fornecedor ou
outros servidores web. É assim que funciona em uma versão
padrão, certo? Certo, então é assim que nosso
primeiro aplicativo Spring Boot realmente funciona. Atualmente,
o aplicativo não faz nada, apenas aceita
conexões no TDAH. Mas se entrarmos em nosso
navegador e dissermos localhost, local, solicit, local host TDAH, e simplesmente clicarmos nele. Podemos ver que
não temos nada. Na verdade, esse erro
vem do Spring Boot ou
do Tomcat, acredito, porque ele precisa encontrar alguns caminhos para mapear a
solicitação e, por padrão, Patty não tem
nada para mapear. Então, atualmente nosso aplicativo
simplesmente é executado e não
especificamos nenhum tipo de ação a ser executada em uma
interação específica, certo? Então esse é
o estado atualmente, certo? Só temos um aplicativo
que não faz nada. Como podemos dizer a essa
obrigação que ela precisa realizar uma ação específica quando os clientes estão interagindo
com ela de uma maneira específica. Então, por esse motivo,
vamos criar uma classe que é chamada de controlador, controlador
de descanso. E vamos
colocar essa classe em um pacote dedicado chamado
controllers, certo? Acabei de criar o pacote
e, em seguida, vou chamar esse controlador de usuário. Portanto, quando um aplicativo Spring
Boot, um controlador é o
primeiro ponto de entrada para uma solicitação
no aplicativo. Portanto, quando os clientes fazem uma solicitação que precisa acessar
o aplicativo, geralmente eles atingem primeiro
um controlador. Em seguida, com base na lógica que
define
o controlador, a solicitação será propagada
em outros componentes, como veremos mais adiante
neste curso. Então, para ter uma ideia de
como um controlador funciona, vamos criar um método
aqui chamado public void, na verdade public string get user. Este método é um método clássico muito
simples. Ele apenas retorna algo como o usuário John Doe apenas
retorna uma string. E muito importante, esse
método será anotado com get mapping seguido
por getUser aqui. Podemos ter qualquer tipo de string que realmente
deva começar com uma barra,
porque ela precisa ter uma estrutura semelhante a um caminho. Então, o que essa anotação
realmente faz é
criar um caminho ou uma rota
em nosso aplicativo. Então, quando um cliente, um navegador
ou qualquer cliente
HTTP , chama esse caminho. Esse método será chamado diretamente no nosso
aplicativo, certo? Então é assim que isso
realmente funciona. Agora vamos executar
nosso aplicativo novamente
para que essas alterações
entrem em vigor. E vamos apertar
Enter neste caso, certo? Então, como você pode ver aqui, temos essa
corda de volta, certo? Agora, se clicarmos em Inspecionar
para ver a solicitação real, se acessarmos a
guia Rede e
clicarmos em atualizar, podemos ver que o
navegador realmente iniciou essa
solicitação HTTP get nesse URL, localhost 80, 80 GetUser, o navegador por padrão, quando você atualiza qualquer página, ele faz essa solicitação de obtenção. Na verdade, ele faz, na verdade, inicialmente faz
essa solicitação de obtenção. E então ele pode baixar
um pouco de JavaScript de volta, que é executado
pelo navegador, que pode permitir
outras solicitações e assim por diante. Então, na prática, isso
é ainda mais complexo. Mas nesse caso de uso muito
simples, o navegador acabou de
lançar uma solicitação get na qual realmente atingiu nossa API, que retorna esse objeto de
string. É assim que você recupera
os dados da nossa API. Agora, se apenas clicarmos aqui, se clicarmos aqui
na resposta, podemos ver nossa string payload. E se clicarmos aqui
novamente nos cabeçalhos, podemos ver que
nos cabeçalhos de resposta também
obtivemos essas informações aqui. Esses cabeçalhos foram realmente
adicionados pela estrutura. Então, não fizemos
nada para que esses dados
aparecessem aqui. Esses são os cabeçalhos da solicitação. E, a propósito, esse é apenas um tipo de entrada de
informações com valores-chave, certo? E isso é o que o navegador
Chrome realmente adicionou na solicitação ao
nosso aplicativo. Agora, é claro, podemos
alterar esses cabeçalhos
usando os mecanismos do Spring
Boot. Mas uma
coisa muito importante a se observar é que sua estrutura, o nome, o nome da chave dos cabeçalhos
e os valores são, na verdade regulados pelo protocolo HTTP. Então, o protocolo HTTP
e, a propósito, HTTP significa Hypertext
Transfer Protocol. Na verdade, o hipertexto
se refere a HTML, mas é mais uma
nomenclatura legada porque você pode realmente transferir dados
binários usando HTTP. Portanto, o HDP tem várias regras. Qualquer protocolo
tem basicamente uma série de regras que regem
algum tipo de ação. Nesse caso, o HTTP controla a comunicação entre
o cliente e o servidor. Assim, você pode ver basicamente
todos os tipos de detalhes sobre como o cabeçalho
deve ser eliminado. Seus proxies realmente funcionam. Em outras palavras, se um cliente e o servidor
respeitarem as mesmas regras, eles poderão se comunicar
corretamente usando as regras do
protocolo HTTP, além do armazenamento em cache. Mas o objetivo deste
curso não é se
aprofundar no protocolo HTTP porque ele é muito, muito complexo. E muitos detalhes estão
dentro desse tópico específico, talvez para um
curso diferente no futuro. Mas, por enquanto, vamos nos
limitar a esse uso muito básico
desse protocolo. Em resumo, quando você faz uma
solicitação get para um servidor web, você está basicamente
solicitando dados a partir dele. Ao fazer
uma solicitação de postagem, você está entregando alguns
dados para esse servidor. Nesse caso,
definimos um bom mapeamento, o que significa que
instruímos a API, o servidor Web, a permitir solicitações
GET nesse caminho. Também temos pós-mapeamento, o que significa que instruímos
o servidor web a receber dados de clientes externos
em um caminho diferente, por exemplo, bordas. E isso é o que
faremos a seguir. Na próxima palestra,
continuaremos a
criar esse controlador de usuário para explorar ainda mais
essa interação com clientes externos.
4. Como podemos usar solicitações POST?: Então, vimos como
podemos basicamente recuperar alguns dados de nossa API. Agora vamos aprender e
brincar com esse mecanismo de entrada e
saída do Spring Boot, que é o controlador
e a configuração de mapeamento. Uma
coisa muito boa de testar com um navegador é se você
tiver o HTML retornado
do seu aplicativo, porque o navegador
realmente renderizará o HTML. Se dissermos algo
como HTML fechado e depois dissermos corpo, claro que não é, isso
é apenas para fins de teste, apenas para brincar e mostrar que o navegador
renderiza o HTML, apenas qualquer texto aqui. Então, se executarmos isso novamente
e recarregarmos a página, podemos ver que o texto é basicamente renderizado
pelo navegador. Assim, retornamos o HTML, mas ele é renderizado
automaticamente pelo navegador. Agora, quando você tem um servidor
web, normalmente transfere dados em algum tipo de formato,
como JSON ou proto buff. E você realmente não
precisa desse tipo de interação com o navegador, mas pode ser útil se você
tiver esse tipo de caso de uso, apenas retornando o HTML. Agora, em vez do navegador, usaremos um cliente HTTP
dedicado
, chamado postmen. Essa é basicamente
uma ferramenta que possui boa interface de usuário que nos
permite interagir ou testar uma API com diferentes
tipos de solicitações, tipos e diferentes
tipos de cargas que podem configure de
uma forma muito fácil. Então, quando você projeta um serviço web, geralmente brinca com
esse tipo de ferramenta para ver como funciona e
testar coisas diferentes. Portanto, podemos fazer exatamente a mesma
solicitação que fizemos no navegador do Postman
dizendo localhost 80,
80 seguido pelo usuário do Git. E se você clicar em Enviar, verá que o HTML é executado e retornado, certo? Você também pode formatar e
responder de maneiras diferentes. Então, agora,
digamos que queremos retornar uma string de nossa API. Essa string deve, na verdade, ser a representação
JSON do nosso objeto de usuário. Então, vamos primeiro definir um
modelo em nosso aplicativo. Vou criar um novo
pacote chamado model. Aqui, vou
dizer Modelo de usuário. Essa é a aula para nosso usuário. E dentro dela
teremos String,
FirstName e LastName
privados. E digamos que também precisemos
fornecer aos números inteiros uma
associação até d, certo? Que é uma espécie de usuário
premium de platina ou coisas como um único
servidor em nível, em nosso aplicativo, apenas
para testar as coisas. Então, vamos adicionar, primeiro lugar, um construtor. Também vamos adicionar getters e setters para
todos os campos, certo? A ideia inteligente nos ajuda a
fazer isso muito, muito bem. O único controlador
que vamos
devolver um modelo de usuário, certo? Precisamos importar essa classe. E aqui, quando
retornarmos isso, precisamos dizer o modelo
de Novo Usuário de John Doe e 1234, ok? Claro, brincamos com
aulas no mundo real, brincamos com modelos reais de
objetos. Então, por esse motivo,
precisamos experimentar isso também. Então, quando eu clico
em enviar a resposta, recebemos de volta esse JSON. Então, como você pode ver,
a estrutura realmente converteu nosso objeto em adjacente, basicamente o nosso objeto, um modelo mas serializado em formato
adjacente, certo? E isso foi feito automaticamente no
Spring Would Framework. Agora, se voltarmos
ao controlador, podemos ter uma
situação em que precisaremos
retornar usuários diferentes
com base em um ID, certo? Então, por exemplo,
digamos que temos aqui um mapa, mapa
privado de string
para UserModel, certo? Chame esse mapa de usuário de novo HashMap. Tudo bem, e digamos que adicionamos um pequeno controlador
aqui, controlador de usuário público. E neste mapa
temos dois usuários. Digamos, digamos que no mapa
do usuário que
adicionamos, colocamos
primeiro o usuário John, que tem esse, esse
modelo aqui. E então também colocamos
a usuária Jane, por exemplo e esta é Jane Doe com
diferentes membros por d. Então, basicamente, temos esses
dois usuários neste mapa. E quando queremos obter
o usuário da nossa API, queremos obtê-lo
dependendo do nome, certo? E isso significa que o nome precisa ser fornecido
na solicitação. Portanto, o cliente
deve realmente adicionar aqui um nome que
pode ser uma variável. E esse deveria ser
chamado de nome de usuário, certo? É assim
que você especifica em nós, em um caminho, o fato de
querer extrair uma
variável dele. Então, aqui no nome de usuário, também
precisamos adicioná-lo
aos parâmetros
desse método usando a anotação da variável
path. Aqui, precisamos especificar
o tipo da variável e o mesmo nome exato que
adicionamos no caminho, certo? Portanto, ao fazer uma solicitação, se você disser getUser John diretamente do navegador
ou do carteiro, o valor John
será propagado nessa variável
de nome de usuário. E podemos usá-la como
qualquer outra variável. Então, neste caso,
podemos dizer que o mapa do usuário não recebe o nome de usuário, certo? Então, vamos executar isso novamente. E, na verdade, eu
também pressiono Debug e coloco um ponto de interrupção
aqui para ver se
essa variável é
preenchida corretamente. Então, o aplicativo foi iniciado. Vou voltar ao postman e dizer
getUser dot John e
clicar
em Enviar e arroz, podemos dizer que a
variável de nome de usuário tem o John válido, e ela simplesmente
entrará no mapa e retornará o real objeto, certo? Então, vou
clicar em Avançar e voltar. Podemos ver que
obtemos a mesma coisa. Agora, se usarmos a cadeia, podemos ver que as
variáveis são jogadas
corretamente e pressionamos F9, e podemos ver que
obtemos os outros objetos. Então, essa é a forma como
vocês basicamente fornecem alguns dados para o
aplicativo no caminho, no caminho da solicitação, para que
possam selecionar diferentes
tipos de informações. Isso pode ser um ID de usuário
, pode ser um e-mail, pode ser qualquer coisa assim, qualquer coisa que realmente faça
sentido em seu aplicativo. Agora vamos mudar de assunto e começar a fazer uma pausa nas solicitações, que é a forma como um
cliente pode fornecer dados a um aplicativo. Para o aplicativo Spring Boot, queremos criar um usuário, certo? Vamos dizer criar usuário. Quando criamos um usuário, não
queremos receber
nada em troca, mas você quer atualizar
isso, esse contrato. Em segundo lugar, vamos dizer
aqui, pós-mapeamento, certo? Como queremos
fornecer alguns dados para nossos sites, esses dados
devem ser os detalhes do usuário, certo? O primeiro nome,
o sobrenome e assim por diante. Então, vamos dizer
Adicionar usuário e pronto. E aqui, nos
parâmetros, precisamos
fornecer algo como
resposta, corpo da solicitação. Essa anotação
diz ao Spring Boot que ele precisa
extrair alguns dados do corpo da solicitação e
colocá-los em um objeto. Esse objeto deve ser, por exemplo o modelo do usuário, certo? Então, isso significa que no mapa
do usuário podemos dizer put e podemos dizer user
dot get firstName seguido pelo objeto real. Sim, eu não preciso devolver
nada aqui, certo? Porque o método não
tem nenhum tipo de retorno. Em outras palavras, estou
extraindo o modelo do usuário da solicitação e
colocando-o nesse mapeador de usuário. Vamos fazer isso. E na primeira vez, vou
tentar com um depurador para
ver se o objeto do usuário
está preenchido corretamente. Sim, então o
aplicativo foi iniciado. Então, vou criar
uma solicitação de postagem. Vou criar uma nova
aba aqui no Postman. E eu vou selecionar
aqui o post, certo. Eu vou dizer Adicionar usuário. E aqui no corpo, vou dizer sua linha, e vou selecionar o
aplicativo JSON json aqui. Preciso fornecer um anexo que contenha as
informações reais para o usuário. Não quero criar
que Jason siga o esquema desse objeto
ou do objeto do modelo do usuário, certo? Portanto, você deve transmitir
o nome, sobrenome e o ID
de membro. Eu posso simplesmente
obtê-los na outra guia. E, claro,
vou
preenchê-los com valores diferentes, por exemplo, Daniel, Craig. E isso deve ser um valor
como qualquer número inteiro que quisermos. Se clicarmos em Enviar, podemos ver que recebemos um erro
chamado erro interno do servidor
ou algo aconteceu. Vamos ver o que aconteceu. Então, se formos direto
aqui nos registros, podemos ver que não é possível construir uma instância do modelo de usuário, não existe nenhum criador, como o
construtor padrão. Então, esta é uma seta que você
provavelmente pode ver com bastante
frequência, na verdade, se você brinca
com objetos, com serialização, desserialização,
coisas assim, o que na verdade
nos diz que quando você forneça esse Json, certo? E na primavera, com o que
recebe esse Json, ele basicamente tenta
criar um objeto de modelo de usuário. Mas quando ele tenta criar
esse objeto de modelo de usuário, ele não usa esse
construtor, certo? Que tem esses
três parâmetros. Em vez disso, o que ela espera é ter
um construtor
sem parâmetros para simplesmente
criar uma instância. E então espera usar os métodos setter para definir todos esses três
campos um por um. Isso é o que realmente a estrutura da civilização
Jackson realmente espera, certo? Esse é o componente
dentro do trampolim que lida com serialização
e desserialização. Então, em outras palavras,
só precisamos fornecer aqui um construtor padrão
sem parâmetros. E funcionará criando novamente,
executando novamente o
aplicativo com o modo de depuração. Deveria ter começado. Está bem? Agora, voltando ao Postman
e clique em Enviar, e diz que
temos um pedido incorreto. Vamos ver qual é o
erro agora que diz que valor numérico do erro de análise
JSON está fora do intervalo, certo? Parece que esse
número que adicionamos aqui está fora do intervalo de
números inteiros, então só precisamos adicionar um número
menor aqui, certo? Agora, se clicar em Enviar,
podemos ver que funciona. Portanto, se clicarmos
nesse parâmetro do usuário, podemos ver que ele é preenchido
com os valores corretos. E se clicarmos em F9 para
continuar a execução, o valor deverá ser
armazenado no mapa. Então, se eu estiver usando a outra guia
para chamar getUser para Daniel, podemos ver que recebemos a
resposta correta. Então, é assim que realmente
adicionamos dados à nossa API.
5. Como implementar respostas padrão: Uma coisa que eu também
queria mencionar sobre funcionalidade
desses controladores é que, geralmente, quando você
joga com microsserviços, você precisa ser capaz de especificar o status correto de sua
introdução para seu pedido. Nesse caso, podemos ver
que só temos Status 200 para todas as solicitações que
fizemos . Essa é a padrão, status 100, ok? Em HTTP, protocolo significa que a interação
acontece com sucesso e tudo funcionou bem. Agora você também pode pesquisar se
o status HTTP está online, e essa é a lista completa dos status mencionados
por um protocolo, certo? Então, por exemplo, se você tiver
o status 500-599, isso deve ser um erro do servidor. As respostas bem-sucedidas são de 200 a 299. E isso também terá todos os tipos de status, como se
você respondesse com 201, isso significa que você criou
o recurso com sucesso. Todos os tipos de modelos de
interação que aconteceram em seu
aplicativo, certo? Tão bem desenhado. Os servidores Web, as respostas e o status do seu
aplicativo devem refletir o que realmente
aconteceu em seu aplicativo
por meio desse código de status. E na primavera teria
uma maneira de fazer isso
nos controladores usando um objeto que precisamos retornar
em cada método, que é chamado de entidade de resposta. E essa entidade de resposta
é de um tipo genérico. Também podemos adicionar aqui o objeto de status
http, por exemplo e o que isso realmente
significa é que podemos retornar desse método
algo como retorno, entidade de
resposta,
resposta, entidade, ponto aceito, ponto construído
responsabilidades. Ele segue um padrão de construção. E quando dizemos aceito aqui, isso significa que adicionamos esse status
HTTP aceito, que é 20.2 na
resposta, certo? Nós construímos esse objeto. Então, basicamente, agora, quando executamos o aplicativo e
criamos um novo usuário. Então, agora, quando vamos e carteiros
novamente dizemos Adicionar usuário, fornecemos aqui alguns dados. Clicamos em Enviar. Podemos ver que
na resposta
chegamos a zero para aceitá-la, certo? Que é um código de status
que adicionamos aqui. Isso, é claro, para
a melhor prática de sua, de sua inscrição, certo? Agora, a mesma coisa pode ser feita aqui e em todo lugar
em seu aplicativo, em qualquer controlador você deve ter esse tipo de interação. Também preciso mencionar que
no controlador interno, você também pode ter outros
tipos de métodos, certo? Também gerenciado pelo protocolo
HTTP, por exemplo, se você pesquisar métodos HTTP, na verdade este,
você pode ver que obtemos vários
métodos aqui, certo? Então, até agora, usamos os métodos
GET e post. Mas você também pode colocar o
cabeçalho, excluir, conectar opções, bandejas, adesivos, e essas são todas elas. Por exemplo, se quisermos
usar delete, certo? Se quisermos
excluir um usuário, por exemplo, só
precisamos ir aqui,
copiar esse método, digamos, excluir o mapeamento. E aqui precisamos
identificar o usuário, por exemplo, precisamos dizer excluir usuário
seguido por um nome de usuário, que é novamente um parâmetro de
variável de caminho, certo? Então, podemos dizer aqui, remover seguido pelo nome de usuário, o que significa que acabamos de tirar
o usuário do nosso mapa. E quando devolvemos a entidade de
resposta, podemos simplesmente dizer
excluída ou nutrição se houver algum status
sem conteúdo, pode ser usada para
operações de exclusão, certo? Então, se apenas recarregarmos
o aplicativo agora
e, a propósito, quando
reiniciarmos o aplicativo, que é a única maneira de
as alterações entrarem em vigor, o mapa ficará vazio novamente, então somente esses dois usuários o farão ser adicionado a partir do
construtor, certo? Então, se adicionarmos alguns usuários e pararmos o aplicativo
e reiniciarmos novamente, os novos usuários não estarão no mapa quando a parte superior
for reiniciada, certo? Porque é claro que está
armazenado na memória. Então, vamos ver, queremos que o usuário Daniel volte,
deveria estar aqui, na verdade agora, ou
precisa ser o usuário John, certo? Então esse é o usuário, e agora queremos excluir. Então, queremos criar uma
nova guia e dizer Excluir. Esse é o tipo de solicitação de
exclusão (método de solicitação para ser mais preciso. E eu vou dizer
exclua o usuário seguido por John, escreva, exclua. Por enquanto, diz para zero o conteúdo, o que significa que
exclui o que é bem-sucedido. E então vou clicar em Enviar novamente para obter o usuário John. Novamente, vejo que
não tenho nada. É claro que também podemos reformular isso um pouco
para dizer algo como se o mapa do usuário contivesse o nome de usuário
chave
, eu o
retornarei diretamente. Caso contrário, vou
dizer que retorna uma entidade de resposta
não encontrada, construída. E aqui, é claro,
preciso retornar uma entidade de resposta do modelo de usuário. E aqui eu preciso dizer entidade de
resposta desta. E isso deveria ser,
na verdade,
opcional, desta vez. Então, em outras palavras, se eu tiver o usuário no mapa, eu retornarei o usuário real. Mas se eu não fizer isso, vou retornar não encontrado, que é 404, certo? Então, vamos repetir a
obrigação novamente para ver essa funcionalidade
em ação, certo? Então, vou trazer
um usuário John de volta. Posso ver que o tenho
porque acabei de reiniciar aplicativo e
os dados preenchidos foram lançados. Na verdade, o construtor está no mapa. Agora, eu quero excluir
um usuário John, certo? Quando recebo o usuário John de volta, vejo que tenho 404
não encontrados e não 200. Ok. É assim que
podemos, é claro, atualizar o status HTTP para refletir a operação correta que ocorreu em
outro aplicativo. Tudo bem, então, com isso, aprendemos sobre como
podemos jogar com controladores, como podemos obter alguns
dados de clientes SAP, do Postman e
também como
podemos recuperar
os dados de maneira adequada. Agora, vamos mudar de assunto e falar sobre serviços no framework
Spring Boot.
6. Como criar serviços no Spring-Boot: Tudo bem, bem-vindo
de volta. Então, até agora, trabalharemos com
o controlador restante. Vimos como podemos adicionar e obter informações de
nosso aplicativo Spring Boot como um cliente HTTP e também jogar com o Postman para
iniciar suas solicitações. Agora vamos continuar com uma mudança estrutural em relação ao aplicativo porque, como
mencionei inicialmente, um controlador de descanso é o
ponto de entrada do seu aplicativo. Portanto, ele permite que você
especifique como você deve obter os dados de seus
clientes e também como devolvê-los. Mas geralmente esses componentes
devem realmente encaminhar a interação dentro do seu aplicativo em
outras estruturas. Em outras palavras,
você não deve adicionar lógica de
aplicativo
ou não deve se conectar a um banco de dados a partir do
seu controlador de riscos. Você só deve obter os
dados no modelo que
deseja e depois chamar um componente
diferente, uma classe diferente em que sua lógica deve
ser executada, certo? O primeiro componente desse
tipo em que vamos nos
aprofundar agora
é chamado de serviço. Então, vamos criar aqui um novo pacote chamado serviços. Pode parecer que estou criando aqui um pacote para cada classe, mas na verdade estou criando um pacote para cada
categoria de classe. Porque se você quiser
adicionar seus modelos, você tem um pacote dedicado para os mesmos quatro controladores, serviços e outros aspectos. Então, normalmente você deve
estruturar seu código
dessa forma para
torná-lo escalável. Então, vou ligar para
esse serviço de usuário. Agora, um serviço no Spring
Boot é apenas a classe anotada com a anotação do
serviço. E o que essa anotação
realmente faz é permitir que seu aplicativo seja visto
na estrutura de injeção de dependência do Spring Boot ou registre sua
classe nessa configuração. Então, em outras palavras, se clicarmos nessa
interface para ver o que está por trás dela ou para
ver a implementação. Podemos ver que essa notação é basicamente uma interface
porque é
assim que você pode criar
anotações em Java. E também tem essa anotação de
componente, que é a anotação raiz no Spring Boot e
também em outras. Agora, o único papel funcional
dessa anotação é o
que mencionei
anteriormente, certo? É que ele registra a classe na estrutura de
injeção de dependência. E também tem um papel
informativo, certo? Ele indica que se
espera que essa classe faça algum tipo
de lógica de computação, chamando serviços externos
ou fazendo algumas validações, ou faça qualquer tipo de lógica que tenha algo a ver
com o usuário gestão. Então, vamos mover
essa parte aqui com o armazenamento do mapa do usuário para esse serviço de usuário e também para essa
inicialização específica. Vamos colocá-lo no controlador
de serviço de usuário aqui mesmo. E é claro que não
teremos acesso a esse mapa
no controlador agora. Precisamos criar alguns métodos que reflitam os que temos
no controlador de resto. Para habilitar essa separação, vamos dizer public,
public, userModel, getUser. E vamos ter
aqui o nome de usuário, certo? Então, vamos dizer
nome de usuário dot ainda. Portanto, essa é uma classe regular, não tem nada a ver específico com o controlador
rest, então não precisamos retornar entidades
de resposta
dos serviços. Essa é uma classe
que se conecta à forma como recuperamos os dados
no cliente HTTP. Então, ele tem um
nível de estrutura moral que está bem. Mas em um serviço ou
genericamente em,
em qualquer classe de componente, podemos adicionar qualquer tipo de código Java simples
básico. Então, isso é getUser. O mesmo para o usuário do AD. Precisamos ter
aqui um modelo de usuário. E aqui, quando
você diz Put of user, e aqui podemos dizer void
ou algo parecido. É claro que precisamos
dizer aqui user.name, firstName e depois user. E não vamos
devolver nada. E também
excluímos usuário, certo? Então, vamos
dizer excluir um usuário pelo nome de usuário, primeiro nome. Na verdade, vamos dizer
remover o nome de usuário. Agora, a questão principal seria: movemos essa lógica para essa classe de serviço ao
usuário, certo? Como trabalhamos com essa
classe do nosso controlador? Porque precisamos ter
na instância do serviço de usuário em
nosso controlador, certo? Ser capaz de fazer
exatamente as mesmas coisas, certo? Adicionar, excluir ou usar. Então, a maneira como fazemos
isso é primeiro, quero dizer,
na verdade existem duas maneiras. Um que não é recomendado
em outro que é recomendado. Então, a primeira
seria criar uma instância do serviço de
usuário, certo? No nível superior à direita, como um campo privado ou na escrita
do construtor. Dessa forma,
criamos essa instância manualmente, certo? Então, desde que o
controlador saia, ele terá uma instância. Essa é uma maneira
de funcionar. Mesmo assim, se precisarmos, se o serviço de usuário tiver um construtor no
futuro, digamos, certo. Um serviço público para usuários, certo? E aqui, ele
precisará de algum tipo de outra classe que diga respeito
apenas ao gerenciamento de usuários,
portanto, não tem nada
a ver com controladores. Então, precisamos atualizar esse
construtor aqui, essa chamada aqui, certo, para poder obter
essa dependência, esse serviço de validação, por exemplo, e fornecido aqui
nesta construção, esse problema está
ficando maior, certo? À medida que mais parâmetros são adicionados porque não teríamos mais
nenhum tipo de desacoplamento entre a lógica de
processamento do usuário e as classes
de saída de entrada, certo? Então, estamos misturando preocupações se fizermos esse tipo de
abordagem aqui. Em vez disso, a
maneira recomendada de jogar com instâncias genericamente na primavera é
usar a configuração de
injeção de dependência da primavera. Portanto, spring with tem esse
padrão muito interessante que também pode ser encontrado em
estruturas externas como juice, por exemplo, Google juice, que é chamada
de injeção de dependência. E, essencialmente, uma estrutura de
injeção de dependência é apenas uma forma de obter instâncias em nosso aplicativo forma desacoplada sem
usar a nova palavra-chave. Porque toda vez que você
usa a nova palavra-chave, você encontra esse problema em que,
quando precisa da classe, também precisa fornecer todas as
suas dependências, certo? E isso é problemático, vai até essa preocupação,
misturar problemas e estrutura de injeção de
dependência permite que você aborde esse problema de uma
forma muito limpa. Então, em outras palavras, o que precisamos fazer
aqui
é criar basicamente
um serviço de usuário
variável de nível privado serviço de usuário
variável e adicioná-lo a esse
construtor aqui. E então podemos dizer que esse serviço de
pontos é igual a serviço, ou podemos renomear este. Na verdade, ele sabe que estamos falando sobre
diferentes variáveis aqui. O escopo de nível um e
o nível de classe um. Mas o que acontece é quando o controlador de usuário está
sendo instanciado, certo? Então, quando a estrutura instancia a
classe do controlador de usuário, percebe que esse controlador de usuário precisa de
um objeto de serviço de usuário e tenta criar uma instância da classe de serviço de
usuário. E isso acontece nos
bastidores. Você não precisa se
preocupar com isso. E diz que o
serviço de usuário não tem nenhum parâmetro de construtor
e apenas cria a instância como você
faria, a nova palavra-chave. Em vez disso, se o serviço
de usuário algum parâmetro
no construtor, pesquisaremos a estrutura e tentaremos criar uma instância para esses
parâmetros também. E será assim
recursivamente, certo? Até que ele consiga
criar todas as instâncias
que precisam ser resolvidas. Se conseguir
criar uma instância, ela simplesmente falhará
no tempo de compilação. Isso é muito útil
porque você pode ver isso imediatamente. Então, vamos ver isso em ação. Então, eu recebo este
serviço de usuário aqui. E, claro, posso
usar a
chave ou o metal Contém agora mesmo porque ela é interna
ao serviço de usuário. Então, em vez disso, vou dizer apenas entidade de
resposta do serviço ao usuário,
na verdade, o serviço não
recebe usuários por nome de usuário. E, nesse caso, tenho que garantir que getUser retorne null ou
algo parecido. Se eu não tiver a
chave em Adicionar usuário, só
preciso procurar o
serviço dot add usuário
do modelo de usuário que
obtive dos parâmetros. E a mesma coisa que tenho
a dizer sobre a exclusão. Portanto, exclua o usuário pelo nome de usuário. Então, agora vamos
executar nosso aplicativo, na verdade ,
vamos garantir que
ele compile primeiro, certo? Então, vamos
ouvir a depuração para ver um pouco como esse controlador está sendo instanciado, certo? Então, como você pode ver, o
serviço de usuário tem uma instância. A estrutura criou essa,
essa instância de serviço ao usuário. Para nós, essa é a estrutura de
injeção de dependência que criou essa
instância automaticamente. E é muito conveniente, certo? Você só precisa fornecer isso
no construtor e pronto. Você não precisa se
preocupar com a forma como essa
instância é criada. Claro, vamos executá-lo para
ver se ele ainda funciona A funcionalidade deve
ser a mesma, certo? Então eu entendo o usuário John. Eu posso ver que isso funciona. Eu adiciono um usuário, Daniel Craig. Chegou a zero para aceitar isso. Eu solicito para o usuário Daniel. Eu o recupero. Eu excluo o usuário
John. Funcionou. E então, se eu perguntar
por John novamente, parece que não
tenho o usuário John. Vamos ver o que acontece. Normalmente, quando você tem 500, algo deu errado, seja
uma exceção de ponteiro nulo ou algo parecido. Sim, na verdade, temos
aquela NullPointerException. Portanto, no getUser, podemos ver que a
desativação é opcional. Este realmente é gerado se
você tiver um valor nulo aqui. Portanto, precisamos dizer que é anulável. Então, quando você diz
opcional ou anulável, se você fornecer null aqui, isso simplesmente transformará isso
em uma opcional de vazio. Está bem? Vamos tentar esse fluxo novamente para ver como funciona desta vez, certo? Então eu pego o usuário John, agora eu o excluo. E aqui, quando eu
chegar, recuperá-lo, posso
ver 404 Not Found. Certo. Então é assim que funciona. Então, sim, é assim que funciona a estrutura de injeção de
dependência. Funciona nos bastidores
em um trampolim. Agora, quero mostrar
uma prática recomendada que você realmente precisa
internalizar,
porque é absolutamente obrigatória
quando você joga com co-design e cria serviços e joga com o
Spring Boot em geral , ou seja, você geralmente
precisa depender de abstrações, suas classes e não
de classes concretas. E se dermos uma
olhada aqui, podemos ver que a classe
do controlador de usuário
depende da classe de usuário,
da classe de serviço de usuário, que é uma classe concreta. Em vez de ter isso, precisamos criar uma interface
chamada realmente primeiro, precisamos renomear a classe de serviço de
usuário para a
implementação do serviço de usuário I MPL. Eu só vou
resumir isso. E aqui
vou criar uma interface chamada Serviço de
Usuário. E esse serviço de usuário deve
conter esses métodos. Faça com que usuário seja usuário e
exclua usuário vazio. E esse deveria
ser um modelo de usuário, certo? Essa interface
deve, obviamente, ser implementada pela implementação do
serviço de usuário. Como você pode ver, a
ideia do IntelliJ destaca o fato que implementamos
essa interface agora. E essa é a ideia central
por trás dessa estratégia no controlador do usuário, vou solicitar a interface,
a interface de serviço ao usuário, e não a implementação. E o Spring Boot
faz o seguinte. Quando tenta instanciar
um controlador de usuário, ele olha para o construtor, vê
que
precisa de uma interface
e, na verdade, interpreta
isso da seguinte maneira. Portanto, a
classe do controlador de usuário depende de uma classe que implementa a interface de serviço ao
usuário. Por isso, ele tenta pesquisar uma classe que implemente
a interface do usuário. Nesse caso,
temos uma única classe que implementa a interface de serviço ao
usuário. E ele vai criar
uma instância disso. Se você tem várias classes implementando a mesma interface e está solicitando uma
interface e uma classe, então você precisa
ser mais
explícito sobre qual classe você
realmente deseja, certo? E você faz isso usando
a anotação do qualificador. A anotação do qualificador
só permite que você adicione uma string e uma string
que você deseja adicionar aqui. Essa string também deve ser adicionada quando você solicita uma
instância de uma classe, mas também ao
criar essa classe, à direita, na definição da classe. Então, se você tiver duas classes, implemente a mesma interface. Você precisa adicionar um qualificador
para os dois para
que a primavera saiba
qual deles que a primavera saiba deve
fornecer em qual local. Você também pode experimentar e ver como isso funciona em
ação com duas classes. Então, é assim que você
deve realmente criar um serviço em um nível de produção,
digamos, implementação. Isso também
ajuda no teste porque, ao
tentar testar o controlador de usuário, você precisa criar uma nova instância
do controlador de usuário. Mas quando você quiser criar uma, em vez de ter que criar todas as dependências com todas as suas dependências
e assim por diante. Só precisamos marcar uma
interface aqui e fornecer os Dominions eram para
todos esses métodos, certo? E você está pronto. Você não precisa usar
as dependências da implementação do serviço de
usuário
em todas essas coisas. Você só precisa
simular essa interface. E é isso, certo? Experimente também com um
teste de unidade para ver como funciona. Você verá
uma grande diferença em termos da forma como você
implementa os testes. Tudo bem, então, com isso,
vamos começar a próxima
palestra em que chamaremos um serviço externo do nosso aplicativo Spring
Boot.
7. Como adicionar configurações no application.yaml: Bem-vindo de volta. Nesta palestra,
vamos remodelar um pouco essa implementação específica do serviço de
horário Como você pode ver aqui, estamos usando o útero para fazer
uma solicitação get a essa API de horário mundial para
obter a atual hora. Mas você sabe, esse endpoint
pode mudar com o tempo. Talvez você precise usar uma API
diferente ou tenha vários endpoints em
seu aplicativo e queira gerenciá-los
em um único local. Portanto, em vez de
procurá-los em todos os tipos de classes, geralmente
é melhor ter um fluxo de trabalho de configuração em que você possa armazenar todas as constantes e detalhes de seu
aplicativo, que podem ser que deve ser
gerenciado em um único local em um arquivo
de configuração dedicado. Spring Boot tem esse mecanismo de
configuração que é muito simples de usar e se integra muito bem à estrutura de
injeção de dependência. Então, vamos
usá-lo agora mesmo. Então, primeiro de tudo, vamos
para a aula principal. Vamos adicionar
essa anotação para ativar as propriedades de configuração. Isso é necessário porque
usaremos uma anotação
de configuração dedicada que é realmente útil, obrigatória para qualquer arquivo
de configuração. Então, vamos criar um
novo pacote chamado config. E aqui
vamos
chamá-la de time API configure
essa classe. Vamos fazer anotações
com a
anotação de configuração, que basicamente a torna disponível no sistema de
injeção de dependência do Spring Boot,
mas também, mas também informa ao
Spring framework que essa classe deve ser usada para
armazenar dados de configuração. Também vamos
adicionar uma nova anotação chamada propriedades de configuração. E vamos
atualizar isso em um segundo com um parâmetro
dentro dessa classe. Teremos nossos campos, que queremos extrair
do arquivo de configuração. Nesse caso, queremos
obter o ponto final. Então, basicamente, queremos
armazenar este em nosso arquivo de
configuração e também no continente, porque talvez queiramos mudar o continente com base na
configuração interna. Vamos dizer string
privada, endpoint e também continentes. E vamos criar getters e setters
para esses dois campos. E onde vamos
armazenar o arquivo de configuração? Vamos
entrar no
diretório de recursos e criar
um novo arquivo aqui chamado
aplicativo dot YAML,
passando um novo arquivo aqui chamado
aplicativo dot YAML, para Logan,
neste local, recursos, diretamente nos
recursos. diretório. E ele procurará esse arquivo yaml do
aplicativo. Se isso estiver presente, ele examinará as configurações
dentro dele. Então, neste
arquivo de configuração, vou dizer api dot API Endpoint. E aqui
vou colar o endpoint
do nosso aplicativo,
que é esse, e alertar que você também cola aqui o continente, neste caso a Europa. Portanto, ter essa
configuração aqui nos
permitirá armazenar os
dados em um único local. Agora, neste momento, talvez eu configure as propriedades de
configuração. Vamos definir um prefixo
para nossa configuração. Agora, um prefixo para
nossa configuração é basicamente
o que diz o nome, o prefixo sob o qual
nossa configuração para o aplicativo
deve estar localizada no arquivo yaml do aplicativo. Portanto, nesse caso, o valor
do nosso prefixo deve ser API, porque sob essa chave de API, temos esses dois
campos que
queremos armazenar na classe
time config. Em outras palavras, isso nos
permite ter todos os tipos de
configurações hierárquicas, certo? E dependendo do prefixo, você pode selecionar qual área
da configuração deseja
armazenar na sua classe, certo? Porque você definitivamente
não quer ter uma classe grande com todas
as configurações no aplicativo yaml, certo? Tudo bem, então, quando
tivermos
essa classe criada, vamos usá-la na implementação
do serviço de tempo. Vamos basicamente
injetá-lo, certo? Da mesma forma que fizemos com os outros serviços que
adicionamos ao construtor. estrutura de injeção de dependência
cuidou de sua inicialização. Então, vamos dizer que a
configuração da API de tempo do
construtor é onde você deseja armazenar isso em nosso campo,
e pronto. Agora vamos
usá-lo, certo? Então, vamos dizer time API, config dot, GET endpoint. Vamos concatenar
isso com get continent e depois com o fuso horário que obtemos do parâmetro. Também vamos
encurtar isso um
pouco mais nessa linha. Ok, então o ponto final, se dermos
uma olhada na
documentação e no slash, e então temos o continente, que é a Europa, e
então obtemos um fuso horário. Portanto, também precisamos de uma barra
extra aqui porque o fuso horário
é uma sequência direta. Então, precisamos adicionar um navio
negreiro extra. Deveria ser isso. Vamos colocar um ponto de interrupção aqui para ver se isso realmente funciona. Tudo bem, agora vamos
fazer uma solicitação para adicionar um usuário e vamos
dar uma olhada
nessa hora chamada configuração de API. E podemos ver que
nossos valores foram
preenchidos corretamente
nessa classe. E se fizermos a solicitação, ela deve funcionar como
esperamos, certo? Então, chegamos a zero para ser aceito
se o recuperarmos, sim. Deve funcionar como esperamos. Sim, essa é
basicamente a maneira como
podemos jogar com
classes de configuração no Spring, mas também podemos alterar algumas
configurações padrão que são lidas pelo trampolim, por exemplo, a porta em que nosso
aplicativo está executando, neste caso, o TDAH. Se quisermos usar
uma porta diferente, podemos facilmente dizer a porta 9019
do servidor. E quando percebemos
o aplicativo, Spring Boot lerá essa configuração e
mudará a porta
adequadamente, certo? Como você pode ver, a alteração entrou em vigor imediatamente
na próxima execução. Obviamente, a
documentação abrange todas as configurações disponíveis
que podemos adicionar aqui. Você também pode fazer a
mesma coisa usando o arquivo de propriedades do aplicativo. Portanto, se você estiver pesquisando na
Internet e estiver acessando esse arquivo de configuração, é
praticamente a mesma coisa, exceto que ele tem uma maneira mais curta de especificar o aplicativo de
configurações. Yaml funciona
praticamente da mesma maneira. Então, com isso, vamos começar
a próxima palestra.
8. Como chamar serviços externos por HTTP: Bem-vindo de volta. Normalmente, em um serviço web, você interage com um
banco de dados para obter alguns dados, processá-los e
depois entregá-los aos seus clientes. Ou você interage com um serviço
diferente
para obter alguns dados
ou adicionar alguns dados a esse serviço, a fim de executar algum tipo de fluxo de trabalho comercial que seu aplicativo
deveria
fazer . em nosso aplicativo. Digamos que sempre que
adicionamos um usuário ao nosso mapa, queremos também armazenar
o horário de criação em UTC quando esse usuário foi criado para o
horário de criação desse usuário. E em vez de fazer
isso
chamando os métodos nativos que
temos na API Java, queremos usar uma
API externa em conjunto
para contabilizar
desvios de tempo ou coisas assim. Vamos fazer isso também para dar um exemplo
de como fazer uma
chamada HTTP para uma API externa. Nós vamos fazer isso. Então, a API que
vamos chamar é
chamada de API de horário mundial. É muito simples
. Você só precisa fazer uma solicitação
para esse URL com o fuso horário e recuperar uma largura
de carga JSON algumas vezes, então vamos
usar este. Então, vamos preparar
um pouco todas as aplicações para isso. Vamos criar um novo
serviço que chamaremos de Time Service. Não é necessariamente o melhor nome, mas é o que
vamos usar. Então, vamos fazer uma
anotação com
a anotação do serviço e também
vamos mudar
isso para a implementação do serviço a tempo, certo? E vamos usar a interface de serviço de
horário. Então, quais métodos
precisamos usar para que possamos realmente retornar a hora
real, certo? Obtenha a hora atual, podemos
dizer obtenha a hora atual. E aqui podemos fornecer
algum fuso horário, certo? Que pode ser algo
como uma cidade
na Europa ou em outras
áreas do mundo, queremos aproveitar o tempo. Então, voltando
à implementação, podemos implementar os métodos. Aqui mesmo. Podemos, na verdade, podemos
criar o núcleo, mas agora vamos usar esse serviço em nossa implementação
de serviços. Portanto, no construtor,
podemos solicitar
da estrutura de
injeção de dependência uma instância do
tempo de serviço, pesquisas de tempo de serviço e tempo de serviço que também
podemos armazenar
como um campo privado, o que, aliás, também pode ser definitivo
, certo? A mesma coisa com esta
, porque queremos
criar as instâncias
uma única vez, certo? Então, temos o serviço, o serviço de horário aqui, e vamos
usá-lo apenas no método Adicionar usuário. Obviamente, precisamos de um
campo no modelo do usuário que queremos armazenar
o tipo de criação. Criação. Também preciso do setter e do
getter para este campo. E vamos
criá-lo usando a funcionalidade de
ideias inteligentes. Então, conseguimos um vencedor e também queríamos um setter
para esse campo, certo? Então, vamos mover esses dois métodos para
baixo depois de desconstrutivos. Então, agora temos um lugar
em nosso modelo onde queremos colocar esse tempo
de criação. Só temos que dizer que o serviço de
horário
realmente não está no modelo
do usuário, certo? Quando você diz ponto do usuário,
defina a hora da criação. E aqui precisamos dizer que o serviço de
horário não obtém hora
atual de,
digamos, Amsterdã. Esse deveria ser um momento. Então, digamos que esteja na
Europa por padrão. Amsterdã é a
cidade que queremos. Agora, é claro,
esse fuso horário pode ser obtido de
um serviço externo, serviços de
co-localização,
que detecta a localização com
base no IP do cliente. Assim, você pode expandir isso ainda mais para obter funcionalidades cada vez mais
complexas. Mas, neste caso,
vamos deixar como está. A questão principal aqui seria como conseguimos o tempo? Como chamamos isso de API HTTP? Então, para isso, vamos usar um cliente HTTP
chamado union rest. Em Java, podemos
conseguir ser clientes. Também temos uma versão embutida, mas essa é a maneira
mais fácil que conheço de fazer uma solicitação HTTP de um
aplicativo para uma API externa. Então, vamos apenas
importar a unidade de dependência,
enquanto Java, vamos colocá-la no
arquivo de
compilação do Gradle e clicar em Sincronizar. Veja se isso é o certo. 11311. Parece ótimo. Detectou que há uma versão mais recente
dessa dependência. Esse é o único. Então, em nosso serviço de horário, quando queremos saber
a hora atual, podemos dizer algo assim. Union rest dot,
obtenha um URL aqui. E o URL é o
que temos aqui. Mas é claro que ele precisa
incluir esse fuso horário. Então podemos dizer como Jason. Então, o que isso faz é fazer a solicitação e obter
a resposta de volta. Agora, Jason retorna uma
resposta HTTP do node Jason, que é um tipo de dados mais
primitivo. Nós realmente não queremos fazer isso. Também queremos converter
isso em um modelo. Então, vamos ver se temos
outras opções para isso, para esse cliente HTTP. Então, digamos que como objeto, certo? Temos isso como objeto aqui. Também temos a versão assíncrona. Então, quando
dizemos como objeto, precisamos fornecer
aqui uma classe que tenha esse formato da
resposta que
esperamos da API, certo? Então, isso é algo que
precisamos criar de dentro e de fora. Então, nos modelos
, podemos dizer o tempo. Ou resposta da API de tempo do cronômetro. Esse pode ser o nome da nossa turma e temos
duas opções, certo? Em, ao definir essa classe, podemos criar um campo para cada par de valores-chave
que temos aqui. Mas como não vamos
usar todos esses campos,
em vez disso, usaremos
somente esse. Não precisamos necessariamente
criar todos eles. Podemos simplesmente criar
apenas este. Então, data e hora UTC, vamos dizer
sequência privada de data e hora UTC, o nome deve coincidir. Podemos adicionar construtores, certo? E também inventor e
setter para esse campo. E vamos mover o
construtor um pouco para cima aqui neste lugar de nível de
classe, vamos dizer json,
ignore, ignore, ignore
propriedades, certo? Então, o que essa anotação
faz é ignorar todas as propriedades
que não
temos aqui como
campos em nossa classe. Nesse momento, apenas extraímos o que precisamos
dessa carga útil. Então, com esse modelo, podemos usá-lo aqui. E você pode ver o
serviço de horário implementado. Podemos ver o tempo de
resposta da API à classe. E podemos tê-lo aqui mesmo. Pegue o corpo, certo. Não devemos esquecer esse
corpo porque, como objeto retorna uma
resposta HTTP do seu tipo. Portanto, precisamos usar
get body para obter o objeto de resposta
real correto. Assim que tivermos essa resposta, podemos dizer que a resposta não
leva você à data e hora, certo, extraindo o campo
da nossa classe. Tudo bem, então vamos ver o que
fizemos até agora, certo? Então, usamos esse serviço para extrair o
tempo dos dois juntos dessa API externa e colocamos esse tempo em um novo campo em nossa classe
UserModel. Agora, bem, é claro que
precisamos ver se isso funciona. Então, vamos atingir esse ponto de interrupção
e reiniciar nosso aplicativo. Também vou
adicionar um ponto de interrupção em
nossa
implementação de serviço de tempo para ver se o carvão foi
feito corretamente. Então, vou
adicionar esse usuário novamente e posso ver essa
resposta, certo? E esse é o único. Então, posso ver alguns dados aqui, o que significa que
recebi a resposta corretamente
dessa API externa. Se você quiser
depurar mais coisas, você também pode remover
esse corpo e usar essa resposta HTTP da API
Time, certo? E então diga ponto de resposta, obtenha corpo, obtenha UTC, data e hora. Porque nessa resposta HTTP, você pode ver mais coisas, como o status do HTTP ou, se
houver algum buffer de dados, todos os tipos de detalhes podem ser
vistos nesse objeto, certo? Então, vou fazer isso de novo. E eu vou ver essa resposta
HTTP
voltando corretamente. Então você pode ver que
obtemos o código de status 200. Você pode ver que não
tivemos nenhum erro. Você pode ver os cabeçalhos que
foram recebidos dessa API. Podemos ver aqui todos eles. E também podemos ver o corpo. O corpo tem isso, esse objeto com nosso tipo de dados, certo, pressione F9 para
continuar a execução. E é isso, certo? Chegamos a zero para aceitar isso. Agora, se recuperarmos o usuário, também veremos esse tempo de
criação porque esse fluxo de obtenção realmente retorna o objeto inteiro e
o exibe na resposta HTTP. Então, isso é basicamente
uma questão de chamar um serviço externo do seu
aplicativo no Spring Boot. Essa é uma forma muito interessante de se conectar com
outros serviços. E na próxima
palestra,
trabalharemos um pouco na implementação do serviço
desta vez para
torná-lo um pouco
mais configurável. Então, com isso, vamos começar
a próxima palestra.
9. Como configurar o MySQL com o Docker: Olá a todos e bem-vindos de volta. Nesta palestra, veremos como
podemos nos conectar a um banco de dados a partir de
um aplicativo Spring Boot. Porque, como mencionei
na palestra sobre serviços, o microsserviço pode
se conectar a um serviço externo para obter
alguns dados ou enviar alguns dados, ou pode realmente se conectar a um banco de dados exatamente da
mesma forma. coisa, certo? Então, de alguma forma, você precisa de
uma forma ou de um local para armazenar suas informações e recuperá-las do
seu aplicativo. E, claro, trazer madeira
tem vários mecanismos que nos permitem
fazer isso de uma forma mais fácil em comparação com, digamos que você esteja
fazendo isso sozinho. E também é
importante ver isso no contexto de ter
vários tipos e
modelos de banco de dados e esquemas de
modelagem de dados. Então, vamos analisar esse exercício
a partir das terras desse complexo,
digamos, ecossistema
de armazenamento de dados que temos no
setor a partir de agora. Então, basicamente, o que vamos
fazer nesta palestra é
substituir esse mapa
do usuário pela minha tabela de sequências, que na verdade terá um
esquema muito semelhante ao que temos
nesse modelo de usuário, certo? Então, praticamente todos
os mesmos campos com,
digamos, com um ID
que servirá como um identificador para um registro
no banco de dados como chave primária. Então, basicamente, esta palestra
terá duas partes. O primeiro será aquele em
que vamos criar um banco de dados e configurá-lo
para criar a tabela real. A segunda parte
será realmente modificar nosso aplicativo Spring Boot para interagir com o banco de dados. Então, vamos começar com
o primeiro passo, certo? Vou abrir meu
terminal e vou
usar o Docker para executar
um contêiner MySQL. Agora, é claro, o Docker não é um pré-requisito para este curso. Não espero que você
saiba como é. Então, por esse motivo, vou fazer uma
pequena introdução a essa tecnologia específica e vou explicar todos os comandos que estou
executando passo a passo. Portanto, pode ser mais fácil
para você acompanhar. Em primeiro lugar, o tempo de execução do
contêiner Docker. Na verdade, você pode ir
aqui mesmo em docs.docker.com. E você pode realmente encontrar
muitos detalhes sobre o Docker
como tecnologia. Resumindo, o docker
é uma tecnologia que nos
permite executar contêineres. E o contêiner é basicamente uma máquina virtual
leve que não requer
um hipervisor, como o VirtualBox, o
VMware ou o Hyper-V. Portanto, você pode basicamente executar
um contêiner usando o Darker se instalar o Docker Engine em seu sistema operacional
e, claro, se
executar alguns comandos. Então, por exemplo, queremos executar MIC chamado container
nesta máquina, eu já tenho o Docker
instalado aqui para Mac. Então, para poder executar
um contêiner MySQL, devo dizer que o
Docker executa menos E, minha senha de raiz quadrada
e, em seguida, um mapeamento de porta
e, em seguida, minha imagem de sequência
seguida pela versão. Então, vamos ver o que esse
comando realmente faz. Docker run significa que eu quero
executar um contêiner
usando o Darker, certo? Então menos e diz, eu quero criar
essa
variável de ambiente e
disponibilizá-la no contêiner. A variável de ambiente é
basicamente apenas um par
de dados de valores-chave que pode ser acessado
em um ambiente específico, seja no
programa atual ou em um contêiner, geralmente no
nível do sistema, certo? Essa é a razão pela qual é chamada
basicamente de variável de ambiente. Portanto, neste caso, quero
definir a senha root para o usuário root porque, para
poder fazer login na minha sequência, precisamos ter a
senha do usuário root. E nesse caso, o valor
da senha
será simplesmente testado. E então menos p significa que eu quero fazer
um mapeamento de portas. Uma porta é basicamente
um identificador para um aplicativo no contexto de um sistema maior com
vários processos. Portanto, um sistema operacional
tem várias portas às quais você pode se
conectar pela rede. E cada porta basicamente
identifica um aplicativo. E o aplicativo pode receber conexões
nessa porta e lidar com elas e receber respostas
e assim por diante, certo? Então, neste caso, quero dizer que quero mapear esse tratado portuário
O6 a partir da minha máquina local. Da máquina quando estou
executando esse comando, que também é conhecido
como host, até
a porta 3306 no contêiner. Agora,
no contêiner deste porto, meu processo secreto realmente
surge. Por esse motivo. Eu escolhi esse retrato, o O6 diretamente no contêiner. Então, em um eixo, o processo por meio dessa porta e da porta do host pode
ser algo diferente. Então, eu posso ter um valor
diferente aqui. E a partir do nosso aplicativo Spring
Boot, quando eu quero me
conectar a esse banco de dados MySQL, eu tenho que especificar essa porta de
host que eu, que eu sento aqui, certo. Agora, para simplificar, posso simplesmente dizer que quero
usar a mesma porta, que é a padrão
da minha escola,
para que não tenhamos outros problemas. Quero dizer, você pode simplesmente ver
se a porta não está correta porque ela simplesmente falhará na
conexão com o banco de dados. Assim, você pode
alterá-lo imediatamente para o correto. O próximo argumento é menos d e menos d representa
eles no contêiner. Então, quando eu executo esse comando, o terminal não espera que o contêiner seja
encerrado ou encerrado. Ele simplesmente iniciará um
contêiner em segundo plano. E o argumento final desse
longo comando é minha sequência, seguida por cálcio,
seguida pela mais recente. Minha sequência é
basicamente o nome
da imagem que queremos rodar. As imagens dos contêineres podem ser encontradas se você estiver
procurando minha imagem de sequência do Docker. E você pode ver este
site, Docker Hub, onde você tem basicamente
todas as imagens que você pode obter
publicamente, certo? Então, eles estão subindo, é basicamente um repositório público de imagens. E essa é
a linha oficial. Então, se você estiver, por exemplo,
se estiver executando este comando docker,
puxe minha sequência. Ele começará a baixar essa imagem diretamente no seu sistema
local, a
partir do repositório remoto. Eu já tenho essa imagem. Faça o download para que eu não
precise baixá-lo novamente. Agora, o que mais recente
realmente significa aqui é a versão da imagem, porque
a imagem pode ter várias tags, ou
certas, ou versões. Atualmente, estou
usando a versão mais recente, mas você também pode usar uma versão
mais antiga se quiser 8031 ou
qualquer outra. Então, vamos executar esse comando. Então, como você pode ver, recebemos esse erro que diz que a
porta já está alocada, provavelmente porque eu tenho
esse contêiner em execução, digamos que docker ps nos diga quais contêineres estão em execução no
momento. Então, por exemplo, eu posso realmente dizer que o docker mata esse contêiner e esse comando
simplesmente destruirá o contêiner
em execução, que foi criado
anteriormente por mim. Então, se eu executar o docker
ps agora, ele diz que não tenho nenhum
contêiner em execução. E se eu executar o comando isso iniciará um
contêiner novamente, o que obviamente seria
um contêiner diferente. Nesse caso, eu recebo de
volta esse ID muito grande, e esse é o ID do
contêiner. Basicamente deve ser um ID exclusivo que o
Docker gera para nós. Agora, se eu dirigir a Corp, sim, posso ver que o
contêiner está funcionando. Eu tenho esse ID aqui
que identifica o contêiner é basicamente uma versão
mais curta deste. Então, posso ver a imagem que
é usada pelo contêiner, seguida pelo primeiro
comando que está sendo executado quando o
contêiner é iniciado. E isso está dentro
da imagem em si, então não podemos controlar
isso e a floresta. Outras
informações importantes sobre esse contêiner são o
status de criação e assim por diante. Além disso, o
mapeamento de portas que vimos anteriormente também é
exibido aqui. Então, temos esse
contêiner funcionando. Agora vamos fazer login nesse
contêiner para que possamos configurar o banco de dados MySQL. Portanto, para fazer login neste contêiner, basta dizer
docker exec menos IT, seguido pelo
ID do contêiner, seguido pelo lote. Então, se isso significa terminal
interativo. Eu quero executar esse comando. Exato significa que eu quero executar esse comando em um
modo interativo neste contêiner. E o comando é
simplesmente Bash, que eu quero que o shell acesse
esses contêineres. Então, se eu executar esse comando, posso ver que o
shell realmente mudou. E isso mudou porque
agora eu estou basicamente executando comandos
no contêiner, certo? Então, eu não estou mais no anfitrião
local. Estou no sistema de arquivos do contêiner e no
sistema de contêiner, basicamente, por exemplo ,
se estou executando o comando ls posso ver que tenho um conjunto
diferente de arquivos, certo, em comparação com o
que obtive antes. Agora, é claro, o
que me interessa
aqui neste contêiner
é acessar o laboratório. Então, para fazer isso, preciso
fazer o login na minha tela. Então, devo dizer que
minha sequência menos U, que significa rota do usuário, login cercado
à direita com um usuário root menos
p e depois Enter, agora tenho que digitar a
senha do usuário root, que na verdade é
essa que eu forneci por meio dessa variável de
ambiente. Então eu posso dizer teste aqui, eu apenas digitei teste
e depois Enter. E eu posso ver isso.
E agora estou logado no meu banco de dados de sequências. Então, a primeira coisa que
preciso fazer aqui, porque esse é um banco de dados
novo. Devo dizer que crie um teste
de banco de dados. Eu quero criar um
novo banco de dados
chamado test e esse comando, agora eu tenho que usar esse banco de dados. Então, eu tenho que dizer use o teste. E agora eu preciso criar uma
tabela dentro desse banco de dados. Então, eu já tenho uma consulta que me permite
criar esse banco de dados, que é esse, certo? Então, eu integro essa entidade de usuário da
tabela, que tem essa chave primária. E eu fiz isso de forma incrementada
automaticamente. E então eu recebi os
campos que já fazem parte do modelo de usuário em nosso
aplicativo Spring Boot, certo, então vou
copiar esse comando, colá-lo aqui e depois a consulta foi executado
com sucesso. Quero obter alguns dados
dessa nova tabela. Claro que vou
obter zero resultados, mas só para ver se a tabela foi criada corretamente, certo? Eu tenho um conjunto vazio. Então, agora o banco de dados
está basicamente configurado. Não há outra coisa a
fazer aqui para permitir ao usuário que o aplicativo
Spring Boot realmente
adicione dados a esse banco de dados.
10. Como configurar nosso aplicativo Spring-Boot para trabalhar com o MySQL: Então, vamos mudar para uma ideia
inteligente para começar a configurar
essas pré-multiplicações. Tudo bem, então a primeira
coisa que precisamos fazer é, obviamente, importar
algumas dependências porque não temos suporte
embutido para acesso a dados
na dependência
web inicial do Spring Boot. Portanto, precisamos adicionar as duas dependências a
seguir. No momento, vamos
ver se precisamos de outros. Ao longo do caminho. Vamos pesquisar
na web por Spring Boot Data,
JPA, Maven Central. Então, JPA significa API de persistência
Java. E o Spring Boot tem uma dependência
dedicada que lida com
qualquer abstração ou, na verdade, é toda
a API que nos
permite acessar
dados usando o Spring Boot. Vamos copiar
essa dependência, Spring Boot starter Data JPA. E então também vamos
pesquisar o conector
MySQL,
Java, Maven Central. Essa é basicamente uma
dependência que nos permite
conectar-se ao meu banco de dados SQL. Basicamente, você
precisa ter um conector para cada banco de dados ao qual
deseja se conectar. E eles devem estar
no mesmo repositório. Então ainda está ligado, na minha central. Mas esta é para
minha sequência e
precisamos , é claro, ser importante. Vou clicar no Gradle
Sync usando o atalho. E, claro,
esperaríamos que o Gradle
escolhesse as dependências
para que pudéssemos começar a trabalhar no projeto. Tudo bem, agora que temos
as dependências ativadas, precisamos fazer as
seguintes alterações. Então, vamos criar um novo pacote que
chamaremos de dados. Então, neste pacote de dados, vou criar uma classe que vou
chamar de entidade de usuário. E essa classe é
aquela que vamos usar para enviar dados
para o banco de dados
e recuperá-los. Então você pode se perguntar por que não usamos a classe
UserModel para isso? Bem, porque essa classe faz
parte do modelo de domínio que usamos para comunicação
com o controlador rest. Ou vi isso, esse esquema
é o que
estamos recebendo
diretamente do usuário usando o Postman. Então, precisamos dissociar
esses dois modelos, certo? Porque talvez não tenhamos
necessariamente a mesma estrutura
em um aplicativo real. De frente e
do lado do cliente, até
o banco de dados de mulheres, podemos ter
modelos diferentes neste andar. Então, por esse motivo, estou
criando um diferente, que basicamente
será muito parecido com este. Então, vou basicamente copiá-lo e colá-lo aqui. Eu vou dizer entidade do usuário. Este é um
pouco diferente
porque precisa implementar uma interface
serializável, certo? Na vida real. Então, a razão pela qual ele precisa
implementar o serializável é porque essa classe será
passada para o banco de dados, certo? Ele precisa corresponder às colunas na
tabela que criamos. Então, como você provavelmente
viu aqui, temos nome, sobrenome, ID de
associação e hora de criação. Então, esses campos são na verdade
esses, mas é claro, escritos com o sublinhado
entre as palavras, certo? Então, eles basicamente precisam combinar os que
temos na tabela. E também precisamos
anotar essa classe com uma
anotação muito importante que se chama entidade, certo? Essa classe, que vem
para Java, Persistence API, basicamente nos diz
que essa classe
precisa ser combinada com a tabela
em nosso banco de dados, certo? Também podemos anotar campos com todos os tipos de anotações
relacionadas à classe da entidade. Assim, podemos personalizar
ainda mais essa classe se tivermos um cenário
mais complexo. Mas, neste curso,
não entraremos em muitos detalhes sobre como
configurar essa classe. enquanto, vamos
simplificar para ver como as coisas se conectam de ponta a ponta. E você também pode explorar mais aspectos dessa área,
se estiver interessado. Então, temos a classe de entidade. O segundo aspecto que
precisamos criar é o repositório do usuário. Agora, o repositório do usuário é
basicamente uma interface que estende o repositório de crédito da entidade
do usuário seguido
por uma string. Então,
por que temos aqui uma interface
chamada repositório do usuário, que é anotada
com um repositório no
qual, na verdade, estende o repositório
crud. Essa interface, que
faz parte do Spring Boot, é basicamente a
principal abstração para um acesso a dados
que fornece operações de criação, leitura, atualização e
exclusão. E também precisamos fornecer
aqui os objetos nos quais queremos executar
essas operações com o curso de banco de dados. E também a chave primária
que queremos usar quando executamos as operações
nessas entidades, certo? Então, como você pode ver nesta
interface, salvamos, salvamos tudo multado
pelo existente por ID. Então, as operações que
podemos executar diretamente. Então, agora que temos esse repositório de
usuários aqui, podemos realmente
usá-lo diretamente em nossa implementação de serviço de usuário. Assim, podemos injetá-lo aqui mesmo, repositório
do usuário, podemos armazená-lo como um campo e também
podemos usá-lo. Por exemplo, no getUser, podemos dizer que retorna o
repositório do usuário dot find by ID. Agora precisamos fornecer uma identificação. Então, adicionamos essa descoberta com o
primeiro nome metal aqui, o que basicamente
nos permite fazer uma consulta em nosso banco de dados usando
o FirstName e a direita, e recuperando uma entidade de usuário. Agora, primeiro, temos esse pequeno
problema de que precisamos
converter a entidade do usuário em modelo de usuário. E para isso, vamos
criar um mapeador
escrevendo uma classe que especialmente, é
projetada para ser convertida de entidade de usuário em modelo de
usuário e vice-versa. Mas antes de entrar nessa parte, também
usaremos
o repositório do usuário
para adicionar alguns dados. Então, para adicionar dados ao banco de dados, precisamos usar o método save. E no método de salvamento,
precisamos fornecer, é
claro, uma entidade de usuário, certo? Vamos
fornecê-lo imediatamente assim que tivermos os
mapeadores criados. Mas também vamos implementar métodos de
exclusão do usuário. Então, vamos dizer que o repositório
do usuário é excluído por nome de usuário, certo? Então, precisamos de outra
consulta aqui. Então, para fazer isso, também precisamos
criar um novo método, excluir pelo primeiro nome. Então, vamos dizer aqui, exclua pelo primeiro nome,
adicionando o nome de usuário. E também precisamos
remover esses mapas de usuário. Na verdade, não
precisamos mais dele. E também vamos criar
a classe de mapeador que mencionei anteriormente. Então, vamos criar um
novo pacote chamado Mappers. Portanto, um mapeador é
basicamente apenas uma classe,
digamos, um
mapeador de entidades do usuário que nos permite converter de um
tipo para outro. Então, vamos realmente criar uma interface
chamada primeiro mapeador de entidades. E essa interface,
digamos, precisa gerar parâmetros e
tem dois métodos. Portanto, o mapeador NFet
basicamente nos permite converter desse
tipo para esse tipo. Então, vamos retornar, você diz mapa, e então vamos considerar a entidade
como t, como um parâmetro. E também fornecemos a operação inversa
em que convertemos, em que obtemos um t
de um que você escreve. Então, digamos que essa é a abstração que
vamos usar. E o mapeador de entidades do usuário
implementará o mapeador de entidades do usuário e do modelo do usuário. Está bem? Então, se implementarmos
esses métodos, podemos ver que o primeiro nos
dará um modelo
de usuário de uma entidade de usuário. O mapa reverso nos dará uma entidade de usuário a partir de um modelo de usuário. Então, também vamos fazer dessa classe um componente, certo? Porque nós o usamos como uma ferramenta. Nesse caso, podemos simplesmente
retornar o modelo de usuário do usuário,
na verdade, a entidade dot FirstName, LastName, ID de associação e hora de
criação, é claro, com um novo e,
claro , este é um um pouco
redundante neste caso, mas em um cenário real,
você terá
esses modelos desviados. Então você precisa adicionar algumas
mudanças aqui, certo? Algumas classes não terão
um parâmetro específico, a outra o terá. Portanto, você precisa fazer algumas conversões aqui para fazer alguma higienização
às vezes. Então, estou fazendo isso mais como
um exercício para saber que isso pode e
acontecerá em um cenário real. Agora, com esse mapeador de
entidades de usuário, vamos injetá-lo na
implementação do serviço de usuário. Mas é claro que vamos
usar a interface, certo, para dissociar as coisas. Então, mapeador de entidades, onde você tem que usar o mapeador de entidades, que é esse, digamos usuário, digamos
que seja mapeador de entidades, para ter certeza de que o recebemos como um campo. E aqui mesmo, onde
encontramos pelo primeiro nome, certo? Então, quando recuperarmos a entidade
do usuário, vamos dizer
mapa porque
temos a entidade e queremos
recuperar o modelo do usuário. Está bem? Então é isso que queremos. Agora, quando queremos
salvar uma entidade, o que você quer dizer
mapeador de entidades mapa reverso de pontos. E vamos
passar para o usuário, certo? Passamos o modelo do usuário, o mapa reverso
recupera uma entidade de usuário que é usada para
a mesma operação. Então, essa é basicamente
a maneira como faríamos isso. Obviamente, não
temos tratamento de erros, não
temos
gerenciamento de exceções nesse código. É basicamente o mais simples
possível para que você possa
ter a ideia principal. Também podemos fazer com que sejam definitivos. E a última coisa
que realmente precisamos nesse aplicativo para
poder nos conectar ao banco de dados é adicionar aqui no aplicativo
a configuração
yaml para o banco de dados, certo? Então, basicamente, endpoint a porta e essa configuração
é a seguinte, certo? Então eu simplesmente colei essa
configuração de um arquivo. O restaurado anteriormente
é basicamente uma configuração de fonte de dados Spring, na
qual passamos a URL, à direita, que inclui
o endpoint uma porta. Essa é a
porta do host, muito importante. Então, o primeiro neste
comando está aqui, certo? Então, esta, a primeira,
a porta do host, seguida pelo nome do banco de dados,
aqui temos o nome de usuário e a senha. Então, com esses detalhes, podemos nos conectar ao banco de dados. Obviamente, existem outros em
aplicativos de nível de produção Você precisa especificar todos
os tipos de configurações de pool de conexões
e muitos outros detalhes. Mas, para manter o exemplo, essa é a
configuração mínima que precisamos fornecer aqui para nos
conectarmos ao banco de dados. Então, vamos executar esse aplicativo no modo de
depuração para ver se ele funciona. Provavelmente não,
porque nunca funciona na primeira tentativa. Então, como você pode ver aqui. Não temos aula. Eles encontraram Java x, x xml. Exceção muito estranha, certo? Normalmente, quando temos
uma classe não encontrada, uma dependência provavelmente é interrompida. E, neste caso, estamos
falando basicamente sobre essa dependência, J XB menos API. Não tenho certeza de
qual é o problema. Descobri que isso na internet
era um problema comum. Então, vamos adicioná-lo aqui
para ver como funciona, certo? Então, agora diz que
não temos nenhum identificador
especificado para a entidade. Então, isso significa que
precisamos adicionar um identificador para
essa entidade de usuário. O identificador é basicamente um
campo anotado com o ID. Então, no nosso caso, temos que adicionar essa anotação
de
ID, é claro, na chave primária. Em nosso caso, não queremos
necessariamente adicionar, digamos, um ID inteiro
aqui pode não ser útil. Digamos que podemos
experimentá-lo FirstName e ver e ver como funciona, certo? Então, como você pode ver, os
aplicativos foram iniciados. Agora vamos tentar adicionar um
usuário em nosso aplicativo. Então, vamos usar o Safe Metal do método Adicionar Usuário
no Rio para
usar o Postman para adicionar
um usuário, certo? Vamos ver o que diz. Atingimos F9, sem exceção, também
voltamos a zero. Então, isso significa que não há exceção do aplicativo, certo? Portanto, podemos clicar em selecionar
da entidade do usuário. Podemos ver que o usuário
está no banco de dados, o
que, obviamente, é muito bom. Quero dizer, conseguimos adicionar
dados em nosso banco de dados. Vamos também adicionar um usuário diferente. Portanto, parece
funcionar conforme o esperado. Agora vamos tentar
recuperar alguns dados. Então, esse
parece que funciona. Se eu estiver procurando
por Daniel, parece funcionar muito bem, o que é muito bom. Quero dizer, sim, vamos
também excluir um usuário. Sim, então nesta operação
parece que temos um problema, parece que temos um erro. Então, o que diz
é que nenhum gerente de entidade
com uma transação real disponível para o
tópico atual não pode processar de
forma confiável a
remoção do carvão, certo? Portanto, esse erro
nos diz que não temos essa anotação transacional
no método de exclusão. E esse é um
ponto-chave muito importante que eu queria abordar , porque geralmente a
operação de exclusão é muito sensível. Quero dizer, você pode realmente
executá-lo a partir de vários segmentos, de vários fluxos de execução,
digamos porque você pode ter problemas de
simultaneidade. Portanto, você pode
realmente ter problemas de inconsistência, condições de corrida. Para resolvê-los no Spring Boot, você precisa usar essa anotação
transacional, que basicamente nos diz que todas as operações nesse
método relacionadas, é claro, ao repositório
do usuário
serão executadas uma transação que é basicamente uma
operação atômica no banco de dados, que pode ser
bem-sucedida ou falhar, mas não pode ser
executada parcialmente, certo? Então, por esse motivo, precisamos
ter essa
anotação transacional em nosso método para que possamos ter a operação de exclusão
executada corretamente e gravada. Então, vamos também adicionar um novo usuário
para que possamos ver se ele funciona. Excluí o usuário do markets
para ver se isso funciona. Se eu excluir, digamos que
o usuário Daniel, certo? Parece que temos 204,
ok, e o usuário foi
excluído do nosso banco de dados. Então é assim que funciona. Vou deixar você corrigir esse problema com
as entidades do usuário. Então, experimente, veja se você pode usar, você pode encontrar na
documentação e anotação que
nos permitirão gerar um ID. Então, em outras palavras,
você pode experimentar pegar
esse campo de ID aqui
na tabela para adicioná-lo como uma entidade de usuário
somente de campo e
ver se funciona. Veja se podemos
gerá-lo automaticamente a partir do nosso aplicativo Spring Boot
e não da tabela. Então, essa é basicamente
uma maneira de você brincar e cobrir coisas. Veja se funciona, veja
se não funciona. Veja, investigue o porquê.
É assim que você pode, você pode aprender basicamente
todas essas coisas. Portanto, essa é basicamente
uma maneira muito simples acessar um banco de dados ponta a ponta, sem
muitos aspectos complexos. Como mencionei
inicialmente, esse cenário de bancos de dados e versões é realmente enorme, você pode acabar enfrentando todos os tipos de problemas
com dependências, com versões, com que não estão presentes
como vimos anteriormente. Portanto, espere que esse fluxo
não seja perfeito, não
queira ser algo
fácil de alcançar. Então, com isso, passaremos
para a próxima palestra.