Alura > Cursos de Front-end > Cursos de Angular > Conteúdos de Angular > Primeiras aulas do curso Angular 19: criando serviços e consumindo API com HttpClient

Angular 19: criando serviços e consumindo API com HttpClient

Listando dados com o método GET - Apresentação

Introdução ao Curso de Angular

Olá. Meu nome é Nai e quero dar as boas-vindas a este curso sobre Angular.

Audiodescrição: Nai é uma mulher de pele morena, com olhos e cabelos castanhos escuros. Ela está vestindo uma camisa laranja.

Objetivos do Curso

Neste curso, aprenderemos a utilizar o protocolo HTTP para realizar a comunicação do nosso projeto Angular com um back-end. Vamos explorar o projeto que utilizaremos? Neste projeto, estaremos bem acompanhados na companhia dos livros, pois utilizaremos o projeto Organo para organizar nossas leituras favoritas. Implementaremos um CRUD, listando, criando, editando e excluindo livros.

Ferramentas e Tecnologias

Para alcançar esse objetivo, utilizaremos como back-end a ferramenta JSON Server. Do lado do Angular, utilizaremos o HTTP Client e entenderemos como o Angular lida com essas requisições à API.

Conteúdo do Curso

Neste curso, aprenderemos a finalidade dos serviços e como utilizar a injeção de dependências. Exploraremos o padrão Observer, como consumir Observables e utilizar alguns operadores da biblioteca RXJS. Além de implementar o CRUD, também implementaremos um gerenciamento de erros no projeto utilizando uma ferramenta interessante do Angular, o Interceptor, já com a abordagem mais atual, que é o Interceptor Funcional, até Remote.

Pré-requisitos e Expectativas

Para participar deste curso, é necessário ter como pré-requisitos conhecimentos em HTML, CSS, JavaScript, TypeScript e, de preferência, ter concluído os cursos anteriores da formação de Angular. Isso porque lidaremos bastante com componentização e comunicação entre componentes, utilizando inputs e outputs, além da parte de roteamento.

Convite para o Curso

Estamos animados para começar e, se você aceita esse desafio, prepare seu café e venha conosco mergulhar no Angular.

Listando dados com o método GET - Configurando o back-end com json-server

Introdução ao Curso e Desafio do Projeto

Olá, é um prazer tê-los conosco neste curso. Vamos conhecer qual será o nosso desafio? Estamos acessando o navegador e já temos a aplicação do projeto base Organo em execução. Vocês têm acesso a esse projeto base na atividade "Preparando o Ambiente". Caso ainda não tenham passado por lá, é importante seguir as instruções, instalar as dependências, realizar todo o passo a passo e executar a aplicação para que possamos começar.

O Organo é nosso organizador de leituras favoritas. Temos uma listagem de livros organizada por gênero literário. Nosso desafio será implementar essa listagem, além da criação de um novo card. Ao clicarmos no botão "Criar Novo Card", somos redirecionados para um formulário onde podemos adicionar o título, a autoria, selecionar um gênero e também adicionar a URL de uma imagem. Ao clicar no botão de salvar, precisamos que um novo registro seja criado.

Além dessa funcionalidade de criação, também vamos implementar as funcionalidades de editar e excluir, pois os botões ainda não estão funcionando. A funcionalidade de favoritar também será implementada, pois, apesar de visualmente estar mudando, ao recarregarmos a aplicação, esse estado não persiste.

Comunicação entre Front-end e Back-end

Para realizar tudo isso, precisamos entender como fazer a comunicação da nossa aplicação front-end Angular com um back-end, para realizar essas requisições e implementar as funcionalidades. O primeiro desafio é ter um back-end com o qual se comunicar. Será que precisamos aprender uma linguagem de back-end, como Java, para implementar uma API e só depois fazer esses testes? A boa notícia é que não, pois esse é um cenário comum para pessoas desenvolvedoras front-end que precisam se comunicar com um back-end. Existem ferramentas que nos auxiliam com isso, e a que utilizaremos é o JSON Server, uma ferramenta amplamente utilizada.

Instalação e Configuração do JSON Server

Estamos acessando a documentação do JSON Server em npmjs.com. É uma ferramenta que possui quase 300 mil downloads semanais e nos permite criar uma API simulada, uma API fake, onde podemos executar todas essas requisições e implementar as funcionalidades do projeto. Para instalar, é importante que instalemos a mesma versão que será utilizada. Na documentação, há um alerta indicando que algumas versões do JSON Server ainda estão em beta e podem apresentar breaking changes no futuro, ou seja, podem causar problemas no código. Portanto, é interessante que instalemos a mesma versão.

Vamos acessar o GitHub do JSON Server, onde encontramos o passo a passo para instalação. O comando para instalar é:

npm install -g json-server@0.17.4

Especificamos a versão para garantir estabilidade. Para utilizar o npm, que é o gerenciador de pacotes, é necessário ter o Node instalado. Caso ainda não tenham, deixaremos o passo a passo para instalação do Node na seção "Preparando o Ambiente".

Vamos copiar o comando, abrir o VSCode, parar a aplicação com o comando "Ctrl+C", limpar o terminal com clear e colar o comando npm install -g json-server@0.17.4, que é a versão desejada. Se não especificarmos essa versão, ele instalará a última versão disponível, o que não é o que queremos. Queremos essa versão mais estável. Pronto, já foi instalado e podemos utilizá-lo.

Configuração do Ambiente de Desenvolvimento

Agora, vamos acessar o menu lateral esquerdo e criar um passo a passo para conter o back-end dentro do nosso próprio projeto. Dentro da pasta "organocrude", vamos clicar no segundo ícone para criar uma nova pasta, que chamaremos de "back-end". No terminal, digitamos clear novamente para limpar e entramos na pasta "back-end" com o comando:

cd backend

Agora, estando dentro da pasta, digitamos:

npm init -y

Isso cria, dentro da pasta back-end, um arquivo package.json, onde teremos algumas informações sobre esse back-end. Estamos, assim, criando um espaço reservado para esse back-end.

No arquivo package.json, temos informações como nome, versão, descrição e uma seção de scripts que vamos modificar. Além de criar o arquivo package.json, criaremos dentro da pasta back-end um arquivo que conterá todos os nossos dados. Adicionaremos alguns dados iniciais de livros para que possamos realizar buscas. Clicamos com o botão direito na pasta back-end, selecionamos "New File" e criamos um novo arquivo chamado db.json ou dados.json. O nome pode ser escolhido conforme a preferência. Dentro deste arquivo, inserimos um JSON com vários livros:

{
    "livros": [
      {
        "id": "1a",
        "titulo": "O Morro dos Ventos Uivantes",
        "autoria": "Emily Brontë",
        "imagem": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxAREBUQEBIVEhU...",
        "genero": {
          "id": "romance",
          "value": "Romance"
        },
        "favorito": false
      }
      // ... more book objects
   ]
}

Esses dados estarão disponíveis no material de preparação do ambiente, permitindo que sejam copiados e colados.

Configuração do Script de Inicialização

Os registros de livros possuem propriedades como id, título, autoria, imagem, gênero (um objeto com as propriedades id e value) e também a propriedade favorita. No package.json, alteramos o script que está como teste. Não utilizaremos esse script de teste. Mudamos para start e substituímos o conteúdo dentro das aspas duplas por outro comando:

  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "start": "json-server --watch db.json --port 3000"
  },

Esse comando indica que a ferramenta json-server ficará observando as mudanças no db.json, que são nossos dados, e será executada na porta 3000. Assim, em vez de digitarmos todo esse comando para executar o back-end, podemos executá-lo apenas com npm start. Por isso, modificamos esse script.

Testando o Back-end Simulado

Agora, podemos testar esse back-end. Dentro da pasta back-end, é importante, durante todo o projeto, ter duas abas de terminal. Uma aba será utilizada para executar o front-end com ng serve dentro da pasta do projeto, e outra aba para executar o back-end. Caso contrário, ocorrerá um erro. Se houver algum erro na aplicação, verifique primeiro se o back-end está sendo executado. Utilizamos npm start dentro da pasta back-end e pressionamos "Enter". Aparecerá uma mensagem com o comando que será executado, conforme configurado no script, uma mensagem de boas-vindas e a URL. Está sendo executado em:

http://localhost:3000/livros

Se clicarmos com ctrl e clicarmos na URL, ela abrirá em outra tela. Lá, veremos todos os dados que inserimos no nosso db.json. A string longa representa a imagem. Se passarmos na URL /livros/algum-id, por exemplo, o primeiro que aparece, e pressionarmos "Enter", ele nos trará apenas esse registro:

http://localhost:3000/livros/1a

Se acessarmos apenas http://localhost:3000, veremos a página do JSON Server, uma mensagem de boas-vindas, alguns recursos e métodos HTTP que utilizaremos nesta API.

Conclusão e Próximos Passos

Conseguimos configurar essa API simulada, que nos permite utilizar todos os métodos necessários para implementar as funcionalidades do nosso projeto, como listagem, criação, edição, exclusão e favoritar. É uma ferramenta muito utilizada para testes. Precisaremos executá-la durante todo o curso, então não se esqueça de mantê-la em execução. Agora que temos esse back-end instalado e configurado, o próximo passo é entender como fazer a comunicação da nossa aplicação Angular com essa API. Vamos abordar isso no próximo vídeo.

Listando dados com o método GET - Criando um serviço no Angular

Introdução ao Back-end e Componentes

Agora que já temos um back-end funcional com o JSON Server, precisamos obter os dados a partir dele. No momento, estamos acessando o VS Code, dentro da pasta "Páginas", no componente Lista Livros. Se acessarmos o listalivros.component.ts, podemos perceber, na linha 37, que há uma rede de livros que contém vários registros. Esses livros estão simulados, e é a partir daqui que estamos renderizando os livros na aplicação.

Podemos colapsar essa linha e apagar esses registros, pois não queremos dados fixos e simulados; queremos que eles venham do nosso back-end. Ao apagar, ocorrerá um erro no método organizarLivrosPorGênero. Podemos comentar o conteúdo desse método, pois depois vamos refatorar esse componente. Agora, precisamos pensar em como obter esses dados.

livros: Livro[] = [];
organizarLivrosPorGenero() {
  // this.generosComLivros = this.generos.map((genero) => ({
  //   genero,
  //   livros: this.livros.filter((livro) => livro.genero.id === genero.id)
  // }));
}

Separação de Responsabilidades no Angular

Precisamos fazer uma requisição a esse back-end. Onde vamos incluir esse código? Se adicionarmos essa requisição dentro do próprio componente, estaremos adicionando uma responsabilidade a mais a ele. A responsabilidade do componente no Angular deve ser restrita à parte de renderização no template e à lógica associada a isso. Outras lógicas, como gerenciamento de dados e lógica de negócios, não devem ser adicionadas dentro do componente. Para isso, temos outro arquivo.

No Angular, as responsabilidades são bem separadas. Temos um arquivo específico para lidar com gerenciamento de dados, lógica de negócios e requisições a APIs: o serviço. Vamos criar um serviço para centralizar essas requisições. Vamos abrir o terminal com CTRL+J, parar a aplicação com CTRL+C e criar um serviço. O comando é ng g s, ou service, mas vamos usar a forma abreviada. Vamos criar uma pasta chamada "services" e o nome do nosso serviço será livro.service.

ng g s services/livro

Pronto, já foi criado. Vamos executar novamente a aplicação para não esquecer.

ng serve

Criação e Estrutura do Serviço

Podemos fechar o terminal. Se acessarmos o menu lateral esquerdo, perceberemos que foi criada a pasta "services", contendo o arquivo de serviço e um arquivo de testes. Vamos acessar o livro.service.ts. Esse arquivo é uma classe exportada, como podemos ver na linha onde está export class LivroService. Há algumas diferenças em comparação com a estrutura do componente, que é o que estávamos acostumados a ver.

Na linha 3, há um decorator chamado @Injectable. Esse decorator informa que essa classe de serviço é injetável. Isso significa que podemos utilizar essa classe, esse serviço, em outros componentes e até mesmo em outros serviços. A propriedade providedIn indica que essa classe pode ser fornecida no valor root, ou seja, podemos injetar esse serviço em toda a aplicação. Temos também um construtor vazio.

Dentro dessa classe, o serviço será responsável por gerenciamento de dados, lógica de negócios e requisições API. Vamos criar nossas requisições aqui. Primeiro, criaremos uma propriedade chamada private apiUrl, que será a URL do nosso back-end.

private API_URL

Vamos acessar o terminal com CTRL+J e, na aba do back-end, selecionar nosso endpoint. Copiamos e passamos, entre aspas duplas, o endereço http://localhost:3000/livros. Essa é a URL da API onde vamos buscar os dados.

private API_URL = "http://localhost:3000/livros"

Utilizando o HTTP Client no Angular

Agora, vamos entender como o Angular faz essa chamada, essa requisição API.

No JavaScript, já estudamos como fazer uma chamada com o fetch, mas no Angular essa lógica é abstraída. Não utilizamos o fetch de forma explícita, mas sim por debaixo dos panos. Utilizamos o protocolo HTTP, que significa Protocolo de Transferência de Hipertexto, a base da comunicação na web. Os clientes, como o navegador, fazem uma solicitação de algum recurso para os servidores, e o servidor responde com um recurso, uma resposta HTTP. Esse protocolo é um dos mais utilizados para a comunicação na web.

No Angular, ao invés de usarmos o fetch, utilizamos uma classe chamada HTTP Client. Para utilizar essa classe, precisamos acessar o arquivo de configuração chamado app.config.ts. Na parte dos providers, no array de providers, adicionamos uma vírgula na linha 11 e, na linha 12, passamos provide HTTP Client e abrimos e fechamos parênteses. Com esse provide HTTP Client, conseguimos fazer requisições HTTP e comunicar com o back-end.

import { provideHttpClient } from '@angular/common/http';
//...
providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideAnimationsAsync(),
    provideHttpClient() // Added line
]
//...

Após isso, podemos fechar esse arquivo e voltar para o service. No construtor, injetamos essa classe do Angular.

constructor(private httpClient: HttpClient) { }

Implementação do Método de Obtenção de Livros

No Angular, utilizamos um padrão chamado injeção de dependências. Dependência é tudo que uma classe precisa para funcionar, como um objeto ou outro serviço. No Angular, ao invés de lidarmos manualmente com isso, criamos uma dependência e, ao invés de declarar uma propriedade chamada HTTP Client e instanciar esse HTTP Client, apenas recebemos essa classe de fora com a injeção de dependência. Esse padrão é muito utilizado em outras linguagens de programação também, mas no Angular fazemos isso dentro do construtor. Criamos uma propriedade, nomeada como HTTP Client para facilitar, e a tipamos como HTTP Client. Assim, temos acesso a todos os métodos dessa classe.

Agora que injetamos o HTTP Client, podemos criar o primeiro método, que é o método de obter livros.

obterLivros() {

}

Criamos obterLivros(), abrimos o bloco com chaves, e dentro digitamos return this.httpClient. Quando criamos essa propriedade com o modificador de acesso private, transformamos essa propriedade automaticamente em uma propriedade da classe. Ao digitar o ponto, aparecem diversos métodos para fazer requisições HTTP, como delete, get, patch, post. Para obter dados, utilizamos o método get. Passamos a URL de onde vamos buscar esses dados, que é this.apiurl. Dessa forma, conseguimos obter os dados.

obterLivros() {
    return this.httpClient.get(this.API_URL);
}

Podemos até tipar esse get, passando um array de livros e importando a interface de livros.

obterLivros() {
    return this.httpClient.get<Livro[]>(this.API_URL);
}
import { Livro } from '../componentes/livro/livro';

Recapitulando e Próximos Passos

Recapitulando, no app.config.ts, adicionamos um provedor do HTTP Client, que é a classe de serviço que o Angular utiliza para fornecer acesso a requisições HTTP. Criamos um serviço, pois é uma boa prática separar a parte de gerenciamento de lógica de negócios e requisições API em um serviço separado, chamado service no Angular. No serviço, injetamos o HTTP Client utilizando a injeção de dependências e criamos um método que retorna o array de livros que temos no db.json.

Agora que temos essa requisição, precisamos modificar nosso componente de listagem para renderizar esses livros, e faremos isso em seguida.

Sobre o curso Angular 19: criando serviços e consumindo API com HttpClient

O curso Angular 19: criando serviços e consumindo API com HttpClient possui 146 minutos de vídeos, em um total de 57 atividades. Gostou? Conheça nossos outros cursos de Angular em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Angular acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas