# Conectando com APIs Backend

{% hint style="info" %}
Esta missão ensina como as aplicações React interagem com APIs backend. Aprenderemos a usar a Fetch API para fazer requisições HTTP, gerenciar o estado e os efeitos colaterais com hooks do React, e construir um componente interativo que consome uma API, processando respostas e lidando com erros de forma eficaz.
{% endhint %}

## Vídeo

{% embed url="<https://youtu.be/hTncMAFn0ns>" %}

**Link direto:** <https://youtu.be/hTncMAFn0ns>

## Tópicos

1. **Introdução às APIs e Uso da Fetch API:**
   * Discussão sobre o papel das APIs na comunicação entre frontend e backend.
   * Como usar a Fetch API para realizar requisições GET e POST para um servidor backend.
2. **Hooks para Gerenciamento de Estado e Efeitos:**
   * Detalhes sobre como utilizar os hooks `useState` e `useEffect` para gerenciar o estado e lidar com efeitos colaterais em React.
   * Exemplos práticos de como esses hooks são essenciais para interações dinâmicas com APIs.
3. **Manipulação de Respostas e Tratamento de Erros:**
   * Técnicas para manipular respostas de API e realizar tratamento adequado de erros.
   * Estratégias para garantir que a aplicação se comporte de maneira robusta em cenários de erro.
4. **Construção de um Componente Interativo:**
   * Implementação de um componente que faz requisições a uma API e exibe dados.
   * Inclusão de funcionalidades interativas, permitindo aos usuários enviar dados para o backend e receber respostas que alteram a UI.

## Material de Apoio

### Repositório no GitHub

{% embed url="<https://github.com/SalvatoreAcademy/frontend-missao-aprendizado-iniciante-conectando-com-apis-backend>" %}

### PDF para Download

{% file src="<https://1989749987-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRonehqhrmNdVr43Njmfs%2Fuploads%2Fgit-blob-417700138652ecb6a3eaa293fa1f7d7ce4812f78%2FFrontend%20-%20Iniciante%20-%20Miss%C3%A3o%20de%20Aprendizado%20-%20Conectando%20com%20APIs%20Backend.pdf?alt=media>" %}

### Miro

{% embed url="<https://miro.com/app/board/uXjVNOBw03o=/?moveToWidget=3458764587893333706&cot=14>" %}

## Exercícios de Fixação

{% hint style="info" %}
Use esses exercícios para reforçar o que acabou de aprender. Se errar, leia a explicação para entender melhor o conceito.
{% endhint %}

<details>

<summary>Qual é a função principal da Fetch API no desenvolvimento web?</summary>

A) Instalar pacotes npm automaticamente.

B) Facilitar a comunicação entre o frontend e o backend através de requisições HTTP.

C) Criar componentes React.

D) Inicializar um novo projeto NodeJS.

</details>

<details>

<summary>Resposta correta</summary>

**Qual é a função principal da Fetch API no desenvolvimento web?**

**Resposta Correta**: B

**Feedback**: A Fetch API facilita a comunicação entre o frontend e o backend através de requisições HTTP, permitindo que os dados sejam enviados e recebidos de um servidor.

</details>

***

<details>

<summary>Complete o código para realizar uma requisição GET usando a Fetch API.</summary>

{% code lineNumbers="true" %}

```javascript
async function fetchData() {
  try {
    const response = await fetch('https://api.exemplo.com/data');
    const data = await response.________();
    console.log(data);
  } catch (error) {
    console.error('Erro:', error);
  }
}

fetchData();
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para realizar uma requisição GET usando a Fetch API.**

**Resposta Correta**: `json`

**Feedback**: O método `response.json()` é usado para converter a resposta da Fetch API em um objeto JavaScript.

</details>

***

<details>

<summary>Verdadeiro ou Falso: O hook useState do React é utilizado para gerenciar efeitos colaterais.</summary>

A) Verdadeiro

B) Falso

</details>

<details>

<summary>Resposta correta</summary>

**Verdadeiro ou Falso: O hook useState do React é utilizado para gerenciar efeitos colaterais.**

**Resposta Correta**: B

**Feedback**: Falso. O hook `useState` é usado para gerenciar o estado dos componentes React, enquanto o hook `useEffect` é usado para gerenciar efeitos colaterais.

</details>

***

<details>

<summary>Complete o código para configurar um endpoint que responde com uma lista de personagens.</summary>

{% code lineNumbers="true" %}

```javascript
export const Api = {
  baseUrl: 'https://backend-iniciante-integrar-com-frontend.onrender.com/',

  personagem: {
    endpoint: function () {
      return Api.baseUrl + 'personagem'
    },
    readAll: function () {
      return this.endpoint() + '/'
    }
  },

  buildApiGetRequest: function (url) {
    return _________(url, { method: 'GET' }).catch(function (error) {
      console.error('Erro ao carregar dados: ' + url, error)
      toast.error('Erro ao carregar dados.')
    })
  }
}
```

{% endcode %}

</details>

<details>

<summary>Resposta correta</summary>

**Complete o código para configurar um endpoint que responde com uma lista de personagens.**

**Resposta Correta**: `fetch`

**Feedback**: O método `fetch` da biblioteca fetch é usado para realizar uma requisição.

</details>

## Exercícios de Validação

{% hint style="info" %}
Esses exercícios testarão sua compreensão prática. Revise o feedback para melhorar suas habilidades.
{% endhint %}

### Desafio de Código

Crie um componente React que busque dados de uma API e exiba uma lista de personagens. O componente deve:

1. Utilizar a Fetch API para buscar dados.
2. Gerenciar o estado dos dados usando `useState`.
3. Utilizar `useEffect` para realizar a busca de dados quando o componente for montado.
4. Exibir os dados na interface do usuário.

<details>

<summary>Resposta esperada</summary>

{% code lineNumbers="true" %}

```jsx
import React, { useState, useEffect } from 'react';
import { Api } from './api';

export default function Personagens() {
  const [personagens, setPersonagens] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const response = await Api.buildApiGetRequest(Api.personagem.readAll());
        const data = await response.json();
        setPersonagens(data);
      } catch (error) {
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, []);

  return (
    <div>
      <h1>Lista de Personagens</h1>
      <ul>
        {personagens.map(function (personagem) {
          return <li key={personagem._id}>{personagem.nome}</li>;
        })}
      </ul>
    </div>
  );
}
```

{% endcode %}

**Feedback**: Certifique-se de que o componente está utilizando `useState` para gerenciar o estado dos personagens e `useEffect` para buscar os dados da API quando o componente for montado. A lista de personagens deve ser exibida na interface do usuário.

</details>

### Revisão de Código

{% hint style="danger" %}
**Analise o código a seguir, encontre e corrija o erro.**
{% endhint %}

{% code lineNumbers="true" %}

```jsx
import React, { useState, useEffect } from 'react';
import { Api } from './api';

export default function Personagens() {
  const [personagens, setPersonagens] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const response = await Api.buildApiGetRequest(Api.personagem.readAll());
        const data = await response.json();
        setPersonagens(data);
      } catch (error) {
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, [personagens]);

  return (
    <div>
      <h1>Lista de Personagens</h1>
      <ul>
        {personagens.map(function (personagem) {
          return <li key={personagem._id}>{personagem.nome}</li>;
        })}
      </ul>
    </div>
  );
}
```

{% endcode %}

<details>

<summary>Resposta Correta</summary>

**Erro:** O array de dependências no `useEffect` está incorreto. Deve ser um array vazio para que a busca de dados ocorra apenas uma vez quando o componente for montado.

{% code lineNumbers="true" %}

```jsx
useEffect(function () {
  async function fetchData() {
    try {
      const response = await Api.buildApiGetRequest(Api.personagem.readAll());
      const data = await response.json();
      setPersonagens(data);
    } catch (error) {
      console.error('Erro ao buscar dados:', error);
    }
  }

  fetchData();
}, []); // Correção: array de dependências vazio
```

{% endcode %}

**Feedback**: Certifique-se de que o array de dependências do `useEffect` está correto para evitar chamadas infinitas à API.

</details>

### Projeto Prático

Crie uma aplicação React que inclua:

1. Um componente que busque dados de uma API e exiba uma lista de itens.
2. Funcionalidade para deletar itens da lista através de uma requisição DELETE.
3. Tratamento de erros e exibição de mensagens de erro usando react-toastify.

#### Tarefas

1. **Configuração Inicial**:
   * Inicialize um novo projeto React.
   * Instale as dependências necessárias, incluindo react-toastify.
2. **Implementação dos Endpoints no api.js**:
   * Implemente funções para realizar requisições GET e DELETE.
3. **Criação do Componente React**:
   * Crie um componente que faça uso das funções do `api.js` para buscar e deletar itens da lista.
   * Utilize react-toastify para tratar e exibir erros.

<details>

<summary>Código esperado</summary>

{% code title="api.js" lineNumbers="true" %}

```javascript
export const Api = {
  baseUrl: 'https://backend-iniciante-integrar-com-frontend.onrender.com/',

  personagem: {
    endpoint: function () {
      return Api.baseUrl + 'personagem'
    },
    readAll: async function () {
      try {
        const response = await fetch(this.endpoint(), { method: 'GET' });
        return await response.json();
      } catch (error) {
        console.error('Erro ao carregar dados: ' + this.endpoint(), error);
        throw error;
      }
    },
    delete: async function (id) {
      try {
        const response = await fetch(this.endpoint() + '/' + id, { method: 'DELETE' });
        if (!response.ok) {
          throw new Error('Erro ao deletar item');
        }
      } catch (error) {
        console.error('Erro ao deletar dados: ' + this.endpoint() + '/' + id, error);
        throw error;
      }
    }
  }
};

```

{% endcode %}

{% code title="App.jsx" lineNumbers="true" %}

```jsx
import React, { useState, useEffect } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { Api } from './api';

export default function App() {
  const [items, setItems] = useState([]);

  useEffect(function () {
    async function fetchData() {
      try {
        const data = await Api.personagem.readAll();
        setItems(data);
      } catch (error) {
        toast.error('Erro ao buscar dados');
        console.error('Erro ao buscar dados:', error);
      }
    }

    fetchData();
  }, []);

  const deleteItem = async function (id) {
    try {
      await Api.personagem.delete(id);
      setItems(items.filter(item => item._id !== id));
    } catch (error) {
      toast.error('Erro ao deletar item');
      console.error('Erro ao deletar item:', error);
    }
  };

  return (
    <div>
      <h1>Lista de Itens</h1>
      <ul>
        {items.map(function (item) {
          return (
            <li key={item._id}>
              {item.nome}
              <button onClick={function () { deleteItem(item._id); }}>Deletar</button>
            </li>
          );
        })}
      </ul>
      <ToastContainer />
    </div>
  );
}
```

{% endcode %}

**Feedback Detalhado**

* **Verificação dos Endpoints**: Certifique-se de testar cada rota (`GET` para buscar itens e `DELETE` para deletar itens) e verificar as respostas.
* **Tratamento de Erros**: Utilize o `toast.error` para exibir mensagens de erro em caso de falhas nas requisições.
* **Estrutura**: A aplicação deve utilizar `useState` para gerenciar o estado dos itens e `useEffect` para buscar dados da API quando o componente for montado.

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://salvatore-academy.gitbook.io/dev-fullstack-web/academia/missoes-de-frontend/conectando-com-apis-backend.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
