Fullstack Open: Part 0 — Fundamentos de Aplicações Web

fullstack-open
web
javascript
Anotações e conceitos principais do módulo Part 0 do curso Fullstack Open: protocolo HTTP, DOM, JavaScript e SPAs.
Autor

Vinicius Felix

Data de Publicação

5 de agosto de 2026

Introdução

Toda API que serve um modelo de Machine Learning, todo dashboard de dados em tempo real e qualquer interface de IA conversacional dependem de um mesmo pilar invisível: o protocolo HTTP e a dinâmica cliente-servidor.

Na Part 0 do Fullstack Open, o objetivo é dissecar essa infraestrutura web sob a ótica de arquitetura: o que realmente acontece entre o clique do usuário, a transmissão do payload e a renderização do resultado?

Abaixo, listo as anotações e reflexões sobre requisições web, manipulação do DOM e a transição do modelo tradicional para Single Page Applications (SPAs) — a engrenagem essencial para transformar modelos em produtos de dados reais.

Conceitos Principais

1. HTTP e Comunicação Cliente-Servidor

graph LR
    subgraph WebDocument [Web document]
        direction TB
        doc[Estrutura e Estilos]
        img[image]
        vid[Video]
        adv[Advertisement]
    end

    doc -- "GET index.html<br>GET styles.css" --> web[Web server]
    img -- "GET header.png" --> web
    vid -- "GET video.mp4" --> video_server[Video server]
    adv -- "GET advert.jpg" --> ad_server[Ad server]

    style web fill:#aec1cf,stroke:#333,stroke-width:1px
    style video_server fill:#c9c2d9,stroke:#333,stroke-width:1px
    style ad_server fill:#a9def1,stroke:#333,stroke-width:1px
    style img fill:#fdedcc,stroke:#e5b850,stroke-width:1px
    style vid fill:#f7cece,stroke:#c75959,stroke-width:1px
    style adv fill:#fbe6c4,stroke:#dda84d,stroke-width:1px

A base de todo o desenvolvimento web — e o ponto de partida essencial para o Fullstack Open — apoia-se no modelo cliente-servidor. Compreender esse fluxo não é apenas memorizar comandos, mas entender como dados trafegam através da rede para alimentar desde simples páginas estáticas até arquiteturas complexas de microsserviços e APIs de Inteligência Artificial.

O Ciclo de Requisição e Resposta (Request/Response)

A comunicação na web é estritamente orientada a mensagens. O navegador (cliente) inicia a conversa enviando uma requisição HTTP para um servidor. O servidor processa essa solicitação e devolve uma resposta HTTP.

Esse ciclo assíncrono é a engrenagem por trás de qualquer aplicação moderna: quando uma aplicação web em React precisa buscar uma lista de dados ou enviar um prompt para um modelo de linguagem, ela dispara uma requisição HTTP em segundo plano e aguarda o retorno do servidor sem interromper a experiência do usuário.

A Anatomia de uma Requisição HTTP

Para avançar com confiança na construção de APIs com Node.js e Express nos próximos módulos, é fundamental dominar três componentes de uma requisição:

  1. Verbos HTTP (Métodos): Definem a intenção do cliente sobre um recurso.
    • GET: Solicita dados ao servidor sem provocar alterações de estado (ex: listar registros ou buscar o resultado de um modelo).
    • POST: Envia novos dados no corpo da requisição para criar um recurso ou iniciar um processamento (ex: enviar um formulário ou um payload JSON com dados para treino/inferência).
    • PUT / PATCH: Atualizam dados existentes no backend, seja substituindo o recurso por inteiro (PUT) ou modificando campos específicos (PATCH).
    • DELETE: Solicita a remoção de um recurso específico no servidor.
  2. Headers (Cabeçalhos): Funcionam como o “envelope” da requisição, carregando metadados cruciais.
    • Content-Type: application/json indica ao backend em qual formato a informação está sendo enviada.
    • Authorization: Bearer <token> transporta credenciais de segurança para validar se o cliente tem permissão de acesso.
  3. Corpo da Requisição (Body): Onde trafegam os dados principais nas requisições POST, PUT ou PATCH, geralmente estruturados em formato JSON (JavaScript Object Notation).

A Resposta e os Status Codes

Ao receber a requisição, o servidor responde com os dados solicitados e um Status Code, um código numérico de três dígitos que sintetiza o resultado da operação:

  • 2xx (Sucesso): Indica que a operação foi concluída como esperado (ex: 200 OK para consultas bem-sucedidas ou 201 Created quando um novo recurso é criado no banco).
  • 3xx (Redirecionamento): O recurso solicitado mudou de endereço e o cliente deve ser redirecionado.
  • 4xx (Erros do Cliente): Problemas na requisição enviada pelo cliente (ex: 400 Bad Request para dados inválidos, 401 Unauthorized para falta de autenticação, e 404 Not Found quando a rota não existe).
  • 5xx (Erros do Servidor): Falhas internas no backend (ex: 500 Internal Server Error quando o código do servidor falha ou perde a conexão com o banco de dados).

Dominar esse contrato de comunicação é o alicerce para construir e integrar sistemas fullstack escaláveis, garantindo que o frontend e o backend conversem em perfeito alinhamento.

2. HTML, CSS e JavaScript no Navegador

Para que uma página web ganhe vida, o navegador atua como um maestro orquestrando três linguagens fundamentais:

  • HTML (A Estrutura): Define o esqueleto e o significado do conteúdo (títulos, parágrafos, botões e formulários).

    Exemplo de estrutura pura em HTML sem estilização CSS (Página do CSS Zen Garden sem estilos).
  • CSS (O Estilo): Aplica a camada visual — cores, fontes, alinhamentos e responsividade — tornando a interface atraente e intuitiva.

    Exemplo da mesma estrutura HTML após a aplicação de estilos CSS.
  • JavaScript (O Comportamento): É o cérebro dinâmico. Permite reagir às ações do usuário, validar dados no próprio cliente e fazer requisições assíncronas ao servidor sem recarregar a página.

⚡ Mini-Demo Interativa: JavaScript em Ação

Clique no botão abaixo para ver o JavaScript alterando o estado e manipulando o DOM em tempo real, sem recarregar a página:

Interações: 0

O Fluxo de Carregamento e Execução

Quando você digita uma URL no navegador, uma sequência precisa de passos acontece em milissegundos:

  1. Download do HTML: O navegador baixa o documento principal e começa a interpretar sua estrutura linha por linha (parsing).
  2. Descoberta de Recursos: Ao encontrar tags como <link rel="stylesheet"> ou <script>, o browser dispara novas requisições HTTP para buscar os arquivos CSS e JS.
  3. Renderização: O CSS é aplicado sobre a estrutura do HTML para desenhar os pixels na tela (paint).
  4. Execução do JS: O motor JavaScript do navegador (como o V8 no Chrome) executa o código, podendo manipular a tela em tempo real ou escutar eventos do usuário.

Compreender que o JavaScript roda diretamente no ambiente do cliente (browser) é o ponto de virada para entender o modelo de desenvolvimento web moderno antes de avançarmos para o ecossistema React.

3. Document Object Model (DOM) e Eventos

Se o código HTML é a planta baixa de uma casa, o DOM (Document Object Model) é a casa construída na memória do navegador.

Quando o browser lê o código HTML estático, ele constrói uma representação orientada a objetos composta por “nós” em formato de árvore. O JavaScript não lê o arquivo HTML diretamente; ele interage com essa árvore viva do DOM.

graph TD
    doc["document"] --> html["html"]
    html --> head["head"]
    html --> body["body"]
    head --> title["title: Meu Post"]
    body --> h1["h1: Título Principal"]
    body --> p["p: Parágrafo com texto"]
    body --> btn["button: Clique aqui"]
    
    style doc fill:#e2e8f0,stroke:#334155,stroke-width:1px
    style html fill:#cbd5e1,stroke:#334155,stroke-width:1px
    style body fill:#bae6fd,stroke:#0284c7,stroke-width:1px
    style head fill:#fef08a,stroke:#ca8a04,stroke-width:1px
    style btn fill:#bbf7d0,stroke:#16a34a,stroke-width:1px

Dica💡 Conexão de Conceitos: Árvore do DOM vs. Sistema de Arquivos do Linux

Se você já usou o terminal Linux, essa estrutura parecerá extremamente familiar: - O document equivale ao / (diretório raiz ou root). - As tags container (como <html>, <body> ou <div>) funcionam como pastas e subpastas. - Os elementos finais (como <button> ou texto) funcionam como arquivos. - Um seletor CSS como body > div#app > button funciona exatamente como um caminho de arquivo absoluto (/home/usuario/app)!

Ambos são exemplos clássicos de Estruturas de Dados em Árvore Hieárquica (N-ary Tree).

As Três Operações Fundamentais do DOM

Toda manipulação interativa no frontend resume-se a três passos:

  1. Selecionar (Querying): Localizar o elemento desejado na árvore.

    const botao = document.querySelector('#meu-botao');
  2. Escutar Eventos (Event Listeners): Reagir a interações do usuário (cliques, digitação, movimento do mouse, envio de formulários).

    botao.addEventListener('click', (event) => { ... });
  3. Modificar (Mutating): Alterar o texto, classes CSS, estilos ou adicionar/remover novos nós HTML.

    element.textContent = "Novo texto!";
    element.classList.toggle("destaque");

🧪 Playground do DOM: Adicionando Itens em Tempo Real

Abaixo está um exemplo prático de como o JavaScript escuta o evento de submit de um formulário, previne o comportamento padrão do navegador (event.preventDefault()) e insere um novo nó na árvore DOM:

📝 Exemplo Prático: Manipulador de Eventos & DOM
  • Item inicial carregado no HTML estático

Dominar o fluxo Evento \(\rightarrow\) Seleção \(\rightarrow\) Manipulação do DOM no JavaScript puro (Vanilla JS) é o conhecimento fundamental para compreender por que bibliotecas como o React foram criadas para abstrair essa complexidade.

4. SPA (Single Page Application) vs. Aplicações Tradicionais

Imagine duas experiências completamente diferentes em uma lanchonete:

  1. A Aplicação Tradicional (MPA - Multi-Page Application): Toda vez que você pede um acompanhamento novo, a lanchonete recolhe sua mesa inteira, joga o prato fora e traz uma mesa nova montada do zero com o novo pedido.
  2. A Single Page Application (SPA): A mesa permanece intacta. Quando você pede um acompanhamento novo, o garçom traz apenas aquela porção específica e coloca na sua mesa sem interromper sua refeição.

Na Web, esse garçom é a requisição assíncrona (AJAX / API fetch) e a mesa é a tela do seu navegador.


🔄 O Modelo Tradicional (Multi-Page Application - MPA)

Nas primeiras décadas da web, cada navegação ou envio de formulário resultava em um recarregamento completo da página.

Quando você clicava em um link em um site como a Wikipédia ou em um portal de notícias antigo: 1. O navegador enviava uma requisição GET para o servidor. 2. O servidor consultava o banco de dados e montava um arquivo HTML completo contendo cabeçalho, rodapé, menus e o novo conteúdo. 3. O navegador descartava a página atual, piscava a tela em branco e desenhava o novo HTML do zero.

graph TD
    subgraph Cliente ["Navegador do Usuário"]
        browser["Navegador"]
    end
    
    subgraph Servidor ["Servidor Web Tradicional"]
        router["Roteador Backend"]
        db[(Banco de Dados)]
        template["Engine de Templates HTML"]
    end

    browser -- "1. Clique em link ou Submit Form" --> router
    router -- "2. Consulta dados" --> db
    db -- "3. Retorna registros" --> router
    router -- "4. Renderiza HTML completo no servidor" --> template
    template -- "5. Envia página HTML pronta" --> browser
    browser -- "6. Recarrega a tela inteira" --> browser

    style browser fill:#e2e8f0,stroke:#334155
    style router fill:#bae6fd,stroke:#0284c7
    style template fill:#fef08a,stroke:#ca8a04


🚀 O Modelo Moderno: Single Page Application (SPA)

Com a evolução do JavaScript e a introdução da API XMLHttpRequest (e posteriormente a API fetch), nasceu o conceito de Single Page Application (SPA), popularizado por aplicações como Gmail, Spotify Web, Netflix, Figma e Trello.

Em uma SPA, a aplicação HTML principal é baixada apenas uma vez no primeiro acesso. A partir daí: - O navegador carrega um bundle de JavaScript que assume o controle da interface. - Quando o usuário navega entre abas ou clica em botões, o JavaScript não recarrega a página. - Em vez disso, ele faz uma requisição em segundo plano para o servidor pedindo apenas dados brutos no formato JSON. - O JavaScript recebe o JSON e atualiza apenas o nó específico da árvore DOM necessário.

graph TD
    subgraph Cliente ["Navegador do Usuário (SPA)"]
        spaApp["App JavaScript / React"]
        domTree["Árvore DOM Viva"]
    end
    
    subgraph Servidor ["API Backend / Microsserviços"]
        api["API RESTful / GraphQL"]
        db[(Banco de Dados)]
    end

    spaApp -- "1. Requisita API em segundo plano" --> api
    api -- "2. Busca apenas dados" --> db
    db -- "3. Retorna registros" --> api
    api -- "4. Responde com JSON puro" --> spaApp
    spaApp -- "5. Modifica pontualmente o DOM sem reload" --> domTree

    style spaApp fill:#bbf7d0,stroke:#16a34a
    style domTree fill:#bae6fd,stroke:#0284c7
    style api fill:#c9c2d9,stroke:#6b21a8


📊 Comparativo Direto: MPA vs. SPA

Critério Aplicação Tradicional (MPA) Single Page Application (SPA)
Recarregamento de Tela Ocorre a cada clique/navegação (Flicker visual) Ocorre apenas na carga inicial (Zero flicker)
Resposta do Servidor Documentos HTML inteiros Dados em formato JSON
Renderização (UI) SSR (Server-Side Rendering tradicional) CSR (Client-Side Rendering)
Experiência do Usuário (UX) Semelhante a folhear um documento impresso Semelhante a um aplicativo nativo desktop/mobile
Preservação de Estado O estado local é perdido no recarregamento O estado do JS (player de música, filtros) continua ativo
Exemplos do Mundo Real Wikipédia, sites governamentais clássicos Gmail, Spotify Web, Trello, Twitter/X

🧪 Simulador Interativo: Sinta a Diferença entre MPA e SPA

Experimente o widget abaixo para ver na prática como as duas arquiteturas se comportam quando o usuário solicita novos dados:

⚡ Simulador Interativo: MPA (Tradicional) vs. SPA (Moderno)

Observe o comportamento do Player de Música no topo enquanto você busca novos conteúdos nos dois modos:

🎵
Tocando: Podcast Fullstack Open - Episódio 0
Tocando há 0 segundos...
ATIVO
1. Modelo Tradicional (MPA)

Recarrega a página inteira. O estado da UI (como o áudio) é reiniciado do zero.

Página 1 baixada do servidor.
2. Single Page App (SPA)

Busca apenas JSON via API. O player continua tocando sem interrupção!

Dados atuais: { "page": 1, "status": "ok" }
Nota🧠 Reflexão de Arquitetura: Por que isso importa para Engenharia de Dados e IA?

Quando construímos dashboards interativos para modelos de Machine Learning (usando React, Vue ou mesmo frameworks como Streamlit/Gradio), estamos operando no padrão SPA: o modelo gera predições e responde com payloads JSON leves, enquanto a interface do usuário permanece fluida, responsiva e pronta para novas interações sem recarregar o navegador.

Exercícios e Prática

Abaixo estão documentados os diagramas de sequência desenvolvidos durante a resolução dos exercícios propostos na Part 0 do Fullstack Open:


Exercício 0.4: Diagrama de Criar Nova Nota (Aplicação Tradicional / MPA)

Neste modelo tradicional, ao enviar o formulário HTML (POST /new_note), o servidor responde com um código HTTP 302 Found (Redirecionamento) forçando o navegador a recarregar e reconstruir toda a página via GET /notes.

sequenceDiagram
    autonumber
    actor Usuario as Usuário
    participant Navegador as Navegador (Browser)
    participant Servidor as Servidor (Node.js/Express)

    Usuario->>Navegador: Digita a nova nota e clica em "Salvar"
    Navegador->>Servidor: POST https://studies.cs.helsinki.fi/exampleapp/new_note<br/>Payload: note="Minha nova nota"
    activate Servidor
    Note over Servidor: Servidor adiciona a nova nota ao array de notas na memória
    Servidor-->>Navegador: HTTP 302 Found (Redirecionamento para /notes)
    deactivate Servidor

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/notes
    activate Servidor
    Servidor-->>Navegador: Código HTML (index.html)
    deactivate Servidor

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/main.css
    activate Servidor
    Servidor-->>Navegador: Arquivo de Estilo CSS
    deactivate Servidor

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/main.js
    activate Servidor
    Servidor-->>Navegador: Código JavaScript (main.js)
    deactivate Servidor

    Note over Navegador: Navegador executa main.js que dispara requisição para buscar os dados JSON

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/data.json
    activate Servidor
    Servidor-->>Navegador: Array de notas JSON [{ content: "...", date: "..." }, ...]
    deactivate Servidor

    Note over Navegador: O navegador executa a função de callback e renderiza a lista completa de notas no DOM


Exercício 0.5: Diagrama de Carga Inicial da Single Page Application (SPA)

Ao acessar a versão SPA da aplicação (/spa), o navegador faz o download dos arquivos iniciais. Uma vez carregado o script spa.js, ele assume o controle da renderização e busca os dados de forma assíncrona.

sequenceDiagram
    autonumber
    actor Usuario as Usuário
    participant Navegador as Navegador (Browser)
    participant Servidor as Servidor (Node.js/Express)

    Usuario->>Navegador: Acessa o endereço https://studies.cs.helsinki.fi/exampleapp/spa
    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/spa
    activate Servidor
    Servidor-->>Navegador: Documento HTML estático básico
    deactivate Servidor

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/main.css
    activate Servidor
    Servidor-->>Navegador: Arquivo de Estilo CSS
    deactivate Servidor

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/spa.js
    activate Servidor
    Servidor-->>Navegador: Script SPA JavaScript (spa.js)
    deactivate Servidor

    Note over Navegador: O navegador inicia a execução do spa.js

    Navegador->>Servidor: GET https://studies.cs.helsinki.fi/exampleapp/data.json
    activate Servidor
    Servidor-->>Navegador: Dados brutos em JSON contendo a lista de notas
    deactivate Servidor

    Note over Navegador: O spa.js lê o JSON e monta dinamicamente a lista <ul> no DOM


Exercício 0.6: Diagrama de Criar Nova Nota na SPA

Diferente do modelo tradicional, ao salvar uma nota na SPA, o formulário não redireciona nem recarrega a tela. O JavaScript captura o envio, atualiza o DOM local imediatamente (Optimistic Update) e envia o payload JSON via HTTP POST em segundo plano.

sequenceDiagram
    autonumber
    actor Usuario as Usuário
    participant Navegador as Navegador (Browser / spa.js)
    participant Servidor as Servidor (API Backend)

    Usuario->>Navegador: Digita o texto e clica em "Salvar"
    Note over Navegador: 1. spa.js previne o reload nativo (e.preventDefault())<br/>2. Adiciona a nota no array local<br/>3. Re-renderiza dinamicamente a lista no DOM<br/>4. Limpa o campo de entrada

    Navegador->>Servidor: POST https://studies.cs.helsinki.fi/exampleapp/new_note_spa<br/>Content-Type: application/json<br/>Body: {"content": "Nova nota na SPA", "date": "2026-08-07..."}
    activate Servidor
    Note over Servidor: Servidor processa o JSON e salva a nota no banco/memória
    Servidor-->>Navegador: HTTP 201 Created {"message": "note created"}
    deactivate Servidor

    Note over Navegador: NENHUMA requisição adicional de HTML ou recarregamento de página ocorre!


Conclusão e Aprendizados

A Part 0 do Fullstack Open estabelece a fundação teórica e prática indispensável para qualquer engenheiro de software:

  1. A teia invisível do HTTP: Toda interação web é regida por requisições e respostas baseadas em contratos claros (métodos, headers, payloads e status codes).
  2. A vida dentro da memória do navegador (DOM): Entender a árvore do DOM e como eventos acionam manipulações JS puro é o segredo para compreender a mágica e o valor de frameworks reativos como o React.
  3. A evolução da experiência do usuário (MPA vs. SPA): A transição do recarregamento total da página (SSR tradicional) para consumo de dados JSON em segundo plano (CSR/SPA) foi o grande divisor de águas da web moderna.

Com essa base consolidada, os próximos passos envolvem mergulhar na Part 1, aprendendo a utilizar o React para criar componentes reativos, gerenciar estado com clareza e construir interfaces prontas para o mundo real.