-
Bom, agora chegou a hora de criar
o ponto de entrada para a nossa aplicação.
-
Então é necessário
que o front-end,
-
quando queira requisitar algum dado,
ele tenha um ponto de entrada.
-
Então nós vamos precisar criar
agora os controladores.
-
Então, o que é o controller?
-
O controller é o cara que vai receber
a requisição que está vindo de um cliente,
-
que pode ser um front-end,
pode ser até uma outra aplicação,
-
quando nós falamos
de microsserviço, por exemplo.
-
Nós já temos aqui o serviço, tá?
-
Então, essa classe de serviço
é aquela que é responsável
-
por consumir de fato
ali o nosso repositório.
-
Só que agora nós vamos
criar o nosso controller.
-
Então aqui no pacote controller
nós vamos criar aqui uma nova classe Java.
-
Nós vamos chamar essa classe
de "ContatoController",
-
lembrando sempre de usar esse sufixo para nós
podermos lembrar do que se trata a classe.
-
Vamos pressionar Enter.
-
E legal, então está aqui.
-
A primeira coisa que nós vamos fazer.
-
Lembra quando nós criamos
o nosso "HelloController"?
-
Nós fizemos essas
duas anotações aqui,
-
indicando que nós estamos trabalhando
com o controlador do tipo REST
-
e nós também temos aqui
o mapeamento da requisição.
-
Então nós vamos fazer a mesma coisa
aqui no nosso controlador de contato.
-
Então nós vamos chegar aqui
e vamos marcar aqui o "@RestController",
-
e além disso, nós vamos colocar
aqui também um @RequestMapping.
-
Como que nós vamos fazer
para chegar nessa requisição aqui?
-
Então, inicialmente
nós vamos colocar isso aqui ("/api").
-
Então qualquer requisição
que venha para "/api",
-
esse controlador vai interceptar.
-
E claro, nós vamos ter
agora nossos métodos internos
-
que vão dar complemento
para esse endereço aqui.
-
Bom, lembra que quando eu vou fazer
uma consulta para um endpoint,
-
eu preciso colocar o URL, tá?
-
Então nessa URL nós temos:
o endereço do servidor,
-
por exemplo,
"servidor.com.br".
-
E aí eu preciso do recurso
que eu vou acessar.
-
Então eu posso fazer ali
um "/api", por exemplo,
-
porque eu posso ter outras
coisas dentro desse servidor.
-
Então nós usamos o "/api"
para indicar que eu quero ir para uma API.
-
Então, a primeira coisa
que nós vamos precisar aqui.
-
O controlador vai precisar
do "ContatoService"
-
para poder fazer o consumo
dos recursos lá do repositório.
-
Então nós vamos fazer agora
uma injeção de dependência aqui.
-
Então nós vamos falar o seguinte:
-
"Olha, vou criar aqui um atributo privado
que vai ser do tipo ContatoService,
-
que eu vou chamar
de simplesmente service".
-
Só que assim,
esse atributo precisa ser inicializado,
-
nós precisamos passar ele
na forma de um objeto,
-
então o Spring Boot já oferece para nós
aqui uma forma rápida de fazer isso.
-
Então nós vamos utilizar
a anotação "@Autowired".
-
O que isso vai fazer?
-
Ele já vai passar para
nós esse atributo já inicializado,
-
e aí nós vamos começar a criar nossos métodos.
-
Então, por exemplo,
o nosso primeiro método
-
vai ser um método que vai
retornar um contato,
-
e esse método vai ser responsável
por gravar o nosso contato.
-
E se ele vai gravar, eu preciso dizer
para ele o que ele vai gravar.
-
Então vou passar aqui o objeto.
-
Então nós temos um método público
que retorna um objeto do tipo contato.
-
O nome desse método é gravar.
-
E para gravar nós vamos
passar um contato para ele.
-
Aí nós vamos fazer o seguinte,
-
nós vamos retornar para quem chamar,
esse endpoint chamado "gravar",
-
nós vamos retornar o nosso
"service.gravar(contato)".
-
Então, só para nós darmos
uma relembrada aqui.
-
Se nós formos lá no método
gravar do service, o que ele faz?
-
Ele recebe um contato
e aí ele utiliza o "contatoRepository"
-
para poder fazer a gravação desse contato.
-
Lembra que o repositório é uma interface
que já implementa tudo o que nós precisamos.
-
Então ele já vai fazer isso
para nós de forma automática,
-
sem nós termos que escrever código SQL,
sem ter que fazer nenhum script SQL.
-
Só que aí é o seguinte,
quando nós fizermos a chamada para o gravar,
-
como que o nosso servidor vai
saber que ele tem que direcionar a chamada
-
para esse endpoint aqui?
-
Então nós vamos fazer uma anotação
aqui que vai ser o "@PostMapping".
-
Então qualquer requisição
vinda com o verbo post,
-
direcionado para ("/contatos"),
vai ser direcionado para esse endpoint aqui.
-
Então vamos lá, vamos entender a mecânica
de como isso aqui funciona.
-
O usuário vai fazer uma requisição
para ("/api") e ("/contatos").
-
Como essa requisição é do tipo Post,
então se a requisição vinda
-
para ("/api) ("/contatos") for do tipo Post,
esse vai ser o método,
-
esse vai ser o endpoint
que vai atender essa requisição.
-
Nós vamos ter também um outro método
que vai ser o método para listar
-
todos os contatos do nosso banco de dados.
-
Então esse método vai retornar para nós
uma lista de contato.
-
Nós podemos chamar esse
método de "listarTodosOsContatos(){".
-
Nesse caso, nós não vamos precisar
passar parâmetro nenhum.
-
Então nós queremos uma lista
realmente com todos os contatos
-
e nós vamos simplesmente fazer:
"return service.listarTodosOsContatos () ;"
-
E lógico, para poder chamar esse endpoint,
eu preciso fazer uma requisição.
-
De que tipo vai ser essa requisição?
-
Ela vai ser uma requisição do tipo Get,
-
e vai ser uma requisição que vai
estar mapeada para quem?
-
Para o ("/contatos").
-
Então da mesma forma,
foi feita uma requisição para o nosso servidor
-
na URL ("/api") e ("/contatos").
-
Só que agora eu tenho dois ("/contatos").
-
Como que o servidor sabe
qual dos dois endpoints
-
deve ser entregue essa requisição?
-
Pelo tipo do verbo.
-
Então por exemplo,
se a requisição é do tipo Post,
-
ele vai entregar para esse endpoint.
-
Se a requisição é do tipo Get,
ele vai entregar para esse endpoint aqui.
-
Claro que a assinatura do método,
em conjunto com o tipo do verbo
-
que nós estamos utilizando aqui,
vai fazer com que isso seja possível.
-
Então nós já temos
o "@PostMapping", o "@GetMapping",
-
e nós podemos também fazer aqui
um método para fazer a exclusão, por exemplo.
-
E aí, se nós dermos
uma olhadinha no nosso service,
-
o método para fazer a exclusão é esse daqui.
-
Então nós temos aqui um método
chamado excluir e o que ele precisa receber?
-
Ele precisa receber um id, o id do objeto
que eu quero remover do banco de dados.
-
Então nós vamos retornar lá para o controller
e nós vamos fazer aqui um "public".
-
No caso do excluir, nós vamos retornar
um "void" e nós vamos chamar de "excluir".
-
Só que nesse caso, para nós podermos excluir,
vai ter que ser passado para nós o ID.
-
Qual é o ID do objeto contato que eu quero
excluir lá do banco de dados.
-
E aí nós vamos chamar o "service.excluir(id)",
passando esse ID que foi fornecido para nós aqui.
-
Só que agora como que eu passo
esse ID para a URL?
-
Então de novo, olha, nós vamos
fazer que a anotação,
-
vai ser um "@GetMapping",
porque eu quero obter algo,
-
quero pegar algo que está no servidor.
-
Aliás, desculpa, "@GetMapping" não,
agora nós vamos usar aqui um Delete,
-
"@DeleteMapping" porque
nós queremos excluir
-
e esse Delete nós precisamos também ter aqui
uma URL para completar o ("/api") e ("/contatos").
-
Só que agora nós temos que fazer o seguinte:
eu tenho que conseguir pegar o ID.
-
Então o ID que está sendo passado
aqui no método Excluir,
-
tem que ser passado aqui para a URL,
então nós vamos colocar aqui, olha:
-
um "/" e vamos supor que eu quero
apagar o registro número oito,
-
então ficaria algo assim.
-
Então eu quero excluir
o registro de contatos cujo ID seja oito.
-
Só que nós precisamos colocar aqui
então um parâmetro, tá?
-
Então no lugar aqui do oito,
o que nós vamos fazer?
-
nós vamos colocar isso
daqui ("/contatos/{id}").
-
E aí nós precisamos dizer
para o Spring Boot
-
que esse parâmetro tem que ser
substituído pelo valor que está aqui.
-
Então o que nós vamos fazer?
-
Esse atributo nós vamos marcar
aqui como "@PathVariable",
-
e aí nos estamos dizendo o seguinte:
"Esse valor tem que ser passado
-
para a variável que tem o mesmo nome lá".
-
Então esse ID, o valor do ID
que for passado aqui
-
na chamada desse método,
vai substituir aqui.
-
daí é isso que vai tornar
nossa requisição dinâmica.
-
Nós vamos poder apagar qualquer registro
que nós queiramos com qualquer ID.
-
Outro recurso que nós
podemos criar aqui também, outro endpoint,
-
é o endpoint para fazer a atualização.
-
Então nós vamos fazer aqui um "public",
o atualizar também retorna um contato
-
para quem chamou o endpoint.
-
Nós vamos chamar esse endpoint
de "atualizar" e se eu vou atualizar,
-
eu vou atualizar um contato.
-
Então também é preciso
passar aqui um contato
-
para que nós possamos fazer
a atualização dele.
-
Nós vamos de novo retornar aqui
o nosso "service.atualizar"
-
e passar esse contato que é passado para nós
na hora da chamada do endpoint.
-
E nós vamos também fazer uma anotação.
-
Então nós vamos anotar aqui
com @PutMapping(""),
-
e ele vai direcionar para onde?
@PutMapping("/contatos").
-
Então percebe que tanto o "atualizar",
o "listarTodosOsContatos",
-
e mesmo o "gravar",
percebe que eles vão para a mesma URL?
-
O que faz com que o Spring Boot
consiga direcionar para o endpoint correto,
-
é além do nome da URL,
o verbo HTTP que nós estamos utilizando.
-
Bom, mais uma coisinha,
quando nós fazemos um Post
-
eu preciso passar o contato
que vai ser gravado no banco de dados,
-
então nós precisamos dizer para o Spring Boot
de onde ele vai pegar esse contato.
-
Então aqui no caso do Post, nós vamos
colocar também a anotação "@RequestBody".
-
O que essa anotação
"@Request Body" está fazendo?
-
Está dizendo para o Spring Boot:
-
"Olha Spring Boot, nós vamos fazer
a gravação de um novo contato.
-
Esse contato está vindo numa
requisição HTTP do tipo Post.
-
Você vai buscar por esse contato
no corpo da requisição".
-
Quando nós fizermos uma requisição,
imagina que você está do lado do cliente,
-
então você vai mandar uma
requisição para o servidor,
-
você tem que mandar o
contato que será gravado.
-
Como nós estamos fazendo
uma requisição HTTP,
-
nós temos que mandar esse contato
na forma de um texto,
-
e aí entra o formato JSON.
-
Então o cliente tem que construir
o objeto no formato de texto,
-
só que padronizado em JSON.
-
Quando nós recebemos essa requisição,
nós estamos dizendo para o Spring Boot
-
que ele deve pegar o objeto
no corpo da requisição,
-
ou seja, ele vai olhar
lá no body da requisição
-
e vai extrair o JSON que está lá dentro.
-
E aí nós vamos fazer a conversão.
-
O Spring Boot vai converter esse objeto JSON
num objeto contato de fato
-
para nós podermos manipular
aqui do lado do Java.
-
Então nós já temos aqui
o CRUD básico que é:
-
fazer o cadastro, fazer a leitura,
fazer a exclusão e fazer a atualização.
-
Agora nós temos também lá no nosso
repositório, se nós formos dar uma olhadinha...
-
Nós temos aqui alguns
métodos que nós criamos.
-
Então nós temos aqui, por exemplo,
um "findByNome"
-
e nós temos aqui também
uma lista de contatos pela data de nascimento.
-
Nós podemos construir também
esses dois endpoints lá.
-
Então vamos voltar lá
para o "ContatoController".
-
Vou criar agora esse "findByNome".
-
Lógico que lá no nosso service,
nós temos que ter também o método
-
que vai implementar isso,
então nós temos aqui buscar por ID,
-
listar todos, o excluir, aqui tem
o "mostrarAniversariantes", que é a lista,
-
o atualizar e nós também podemos
implementar aqui no serviço, um public,
-
nós vamos retornar um contato,
e vamos chamar de "buscarPeloNome".
-
Se eu vou buscar pelo nome,
eu vou ter que fornecer
-
uma String carregando o nome.
-
Nós vamos chamar o nosso repositório
"contatoRepository.findByNome(nome);".
-
Legal, e o que acontece aqui né?
-
"findAll"não, "findByNome",
que foi aquele personalizado que nós criamos.
-
E aí nós passamos o nome que foi fornecido
aqui na hora de fazer a chamada para o serviço.
-
Lembrando que nós podemos
receber também aqui um vazio,
-
então é legal nós também utilizarmos
aquela estrutura do "Optional".
-
Nós podemos colocar aqui
um "Optional".
-
Esse cara nós podemos
chamar de "contatoOptional",
-
que vai receber esse carinha aqui.
-
Ele vai receber a resposta desse
repositório que nós construímos lá.
-
Deixa eu dar uma olhadinha
lá no nosso repositório.
-
Ah, ele está recebendo aqui
um contato, né?
-
Então vamos mudar isso aqui.
-
Vamos falar que ele vai retornar
para nós um "Optional",
-
que vai ficar mais legal porque
nós conseguimos tratar se ele estiver vazio.
-
Agora sim, então nós vamos ter aqui
um Optional que vai receber o Optional
-
que está vindo de lá do banco de dados.
-
E aí, o que nós conseguimos fazer aqui?
-
Nós conseguimos fazer o tratamento,
então se o "(contatoOptional)" estiver presente,
-
então o que que nós fazemos?
-
Nós retornamos para quem está chamando
o "contatoOptional.get()".
-
Caso contrário, o que nós fazemos?
-
Nós podemos repetir isso aqui
e nós lançamos uma exceção
-
lá para quem chamou:
("Contato não encontrado!").
-
E aí no nosso controller
nós vamos utilizar esse service aqui
-
de uma forma bem mais interessante,
porque isso aqui pode gerar um erro
-
e vai mostrar uma mensagem
que o contato não foi encontrado.
-
Legal gente, então é sempre assim,
-
você tem o service, que é o cara
que de fato vai consumir o repositório.
-
Lembre que o repositório é feito
automaticamente pelo Spring Boot.
-
Agora nós vamos criar o controller
que vai usar esse service.
-
Então vamos lá,
vamos criar aqui um @...
-
Como ele é uma pesquisa, uma consulta
então ele é um "@GetMapping".
-
Ele vai ser um "@GetMapping"
também aqui para a "/contatos",
-
e nós vamos ter que passar
o nome de quem nós estamos consultando.
-
Então aqui teria que aparecer, seila,
-
eu estou procurando
o usuário que se chama Carlos,
-
mas nós não vamos passar Carlos aqui,
então nós vamos passar aqui um parâmetro.
-
Então vou chamar aqui de
("/contato/{nome}").
-
Nós vamos construir agora
a estrutura do método.
-
Então nós vamos criar aqui um public
e ele vai retornar o quê?
-
Um contato, que nós podemos
chamar aqui de "buscarContatoPeloNome",
-
e vai passar aqui um "(String nome)".
-
Da onde nós vamos tirar essa String aqui,
de onde esse nome vai vir?
-
Ele vai sair daqui, nós vamos
ter que extrair esse nome da URL.
-
Então quem chamar essa URL
vai chamar ("/contatos/carlos").
-
Esse carinha que está aqui,
o Carlos, nós vamos ter que substituir
-
pelo parâmetro da função do método.
-
Então nós vamos chamar aqui
também o "@PatchVariable".
-
Então uma variável no caminho
vai ser substituída no nosso parâmetro.
-
E aí nós vamos fazer simplesmente o quê?
-
"return service.buscarPeloNome(nome);"
passando aqui o nome do usuário
-
que foi passado para nós
na chamada desse endpoint.
-
E nós temos um outro service
que faz a busca aqui.
-
Ele mostra para nós os aniversariantes
de um determinado período.
-
Então nós vamos fazer também aqui mais
um controlador que também é do tipo Get.
-
Então nós vamos chamar aqui o "@GetMapping",
nós vamos passar aqui um ("/contatos/"),
-
e nós vamos assinar esse
método da seguinte forma:
-
vai ser aqui um "public", ele vai retornar
para nós uma lista de contatos,
-
nós vamos chamar de "mostrarAniversariantes",
e nós vamos precisar receber aqui:
-
"mostrarAniversariantes(LocalDate dataInicial)".
-
Aí nós temos que dar
uma olhadinha lá no nosso service.
-
Nós estamos passando primeiro
a data inicial e depois a data final.
-
Então: (LocalDate dataInicial,
LocalDate dataFinal).
-
E agora nós vamos fazer
simplesmente o quê?
-
Nós vamos retornar o nosso
-
"service.mostrarAniversariantes
(dataInicial, dataFinal)".
-
Nós agora precisamos decidir
como que nós vamos passar
-
essas informações aqui na URL.
-
Então nós podemos fazer
algo do tipo assim,
-
nós podemos passar aqui um
("/contatos/{dataInicial}/{dataFinal}").
-
Então nós sabemos que o "contatos",
-
aí nós vamos passar
uma data, "barra", uma data final aqui.
-
E aí nós vamos ter que anotar,
então esse local date aqui,
-
nós vamos tirar também
do "@PathVariable".
-
Assim como nós podemos
tirar esse outro,
-
eu vou quebrar aqui para
ficar mais legal de nós olharmos.
-
Esse outro aqui, nós também vamos
poder fazer aqui um "@PathVariable" também.
-
Legal, gente.
-
Então assim, o básico dos nossos
controladores já está criado.
-
Agora, se nós pensarmos no REST,
o que o REST fala para nós?
-
Então, por exemplo, quando eu faço um Post,
eu envio um objeto lá para o servidor,
-
ele vai pegar esse objeto
que está no formato JSON
-
e vai gravar no banco de dados.
-
Ele tem que devolver
esse objeto que ele criou
-
para quem chamou o endpoint.
-
E aí nós temos as respostas HTTP,
os Status HTTP.
-
Então, se tudo aconteceu com sucesso,
se tudo deu certo,
-
nós devolvemos o código 200, por exemplo.
-
Mas nós temos que definir
que tipo de código 200 é esse.
-
Então, por exemplo, para o Post
nós vamos devolver um 201 que é o Created.
-
Ou seja, eu informo para o cliente
que está consumindo o meu endpoint
-
que o objeto foi criado no banco
e ele está lá gravado, bonitinho,
-
ele está lá persistido no banco.
-
Então nós vamos agora definir
que tipo de código HTTP
-
os endpoints vão responder
para quem chamar os nossos endpoints,
-
para quem chamar
os nossos controladores, tá bom?
-
Então o Post é porque
eu vou criar um objeto novo,
-
então nós podemos colocar aqui
uma anotação que é a "ResponseStatus".
-
Ou seja, qual vai ser o status da resposta
e nós vamos fornecer aqui um HTTP Status
-
e aí nós temos vários tipos de respostas.
-
Nós temos aqui, por exemplo,
o "HttpStatus.CREATED", que é o código 201.
-
Então, quando nós temos um Post,
nós devolvemos uma mensagem 201
-
informando para o consumidor da API
que o objeto foi criado.
-
Aqui, no caso do Get, nós vamos também
devolver um "ResponseStatus",
-
e o padrão ele já vai 200, mas nós vamos
colocar aqui de forma explícita.
-
Então tem um "HttpStatus"
e nós temos aqui o "OK".
-
Então está aqui, olha,
nós vamos devolver um "HttpStatus.OK".
-
Vou copiar esse carinha,
porque para os outros Gets aqui,
-
nós também vamos
responder com o código 200.
-
Ou seja, a consulta ocorreu de forma ok.
-
No caso do Delete nós vamos responder
aqui com um "HttpStatus.NO_CONTENT".
-
Por quê?
-
Como nós excluímos o objeto,
então nós estamos devolvendo para ele:
-
"Olha, o objeto foi excluído, então
não há mais conteúdo para você olhar".
-
Aqui no Put nós vamos
responder também com o 200.
-
Ou seja, a atualização ocorreu
com sucesso no banco de dados.
-
Então os nossos controladores
já estão prontos,
-
já estão ali prontinhos para começar
a receber as requisições dos nossos usuários.
-
Então agora você já sabe como
que você cria a porta de entrada,
-
como que você define
os controladores que vão receber
-
as requisições dos clientes da nossa API.