Objetivo: Substituir o estado local "de mentira" do frontend (app-state) por chamadas reais à nossa API.

Passo 4.1: O Primeiro "Fetch" e o Erro CORS (Intencional)

Objetivo: Vamos tentar buscar a lista de "todos" do nosso backend. Vamos esperar que isso falhe, para que os alunos possam ver por que o CORS é necessário.

Ação 1: Modificar o core.cljs (Frontend) Abra seu src/todo/frontend/core.cljs. Vamos adicionar a lógica para chamar a API.

  1. Adicione os requires de assincronia: No ns, adicione cljs.core.async e cljs.core.async.interop.Clojure

    (ns todo.frontend.core
      (:require [reagent.core :as r]
                [reagent.dom.client :as rdom]
                [clojure.string :as str]
                ;; --- ADICIONE ESTAS DUAS LINHAS ---
                [cljs.core.async :refer [go]]
                [cljs.core.async.interop :refer-macros [<p!]]))
    
  2. Adicione as funções da API: Abaixo do seu app-state, adicione o api-url e as novas funções fetch-json e get-todos.Clojure

    ;; ... (defonce app-state ...)
    
    ;; --- ADICIONE ESTE BLOCO ---
    (def api-url "<http://localhost:3000/api>")
    
    (defn fetch-json [url options]
      (-> (js/fetch url (clj->js options))
          (.then (fn [response]
                   (when-not (.-ok response)
                     (throw (js/Error. (str "HTTP error: " (.-status response)))))
                   (.json response)))
          ;; A CORREÇÃO ESTÁ AQUI:
          (.then #(js->clj % :keywordize-keys true))))
    
    ;; Busca todos os "todos" da API
    (defn get-todos []
      (swap! app-state assoc :loading true :error nil)
      (go
        (try
          (let [response (<p! (fetch-json (str api-url "/todos") {:method "GET"}))]
            (swap! app-state assoc :todos (:todos response) :loading false))
          (catch js/Error e
            (swap! app-state assoc :error (.-message e) :loading false)))))
    ;; --- FIM DO BLOCO ---
    
    ;; ... (função adicionar-todo-local) ...
    
  3. Chame get-todos na inicialização: Encontre sua função init no final do arquivo e adicione a chamada (get-todos) a ela.Clojure

    (defn ^:export init []
      (println "Frontend 'Mini-App Local' inicializado...")
    
      (let [root (rdom/create-root (js/document.getElementById "app"))]
        (.render root (r/as-element [app])))
    
      ;; --- ADICIONE ESTA LINHA ---
      (get-todos))
    

Ação 2: Teste (A Falha Intencional) Agora, vamos rodar ambos os servidores.

  1. Terminal 1 (Backend): Inicie sua API (que não sabe sobre CORS ainda).Bash

    clj -M:run
    

    (Deve dizer Servidor iniciado na porta 3000)

  2. Terminal 2 (Frontend): Inicie seu compilador.Bash

    npx shadow-cljs watch app

    (Deve dizer server running at http://localhost:8000)

  3. Navegador: Abra http://localhost:8000.

Resultado Esperado: A página irá carregar, mas a lista de "todos" (mesmo os do backend) não aparecerá.

A "Lição" (O "Aha!"):

  1. No seu navegador, abra o Console do Desenvolvedor (Pressione F12 ou Ctrl+Shift+I).
  2. Você verá um erro vermelho bem claro na aba "Console".
  3. A mensagem será algo como: Access to fetch at '<http://localhost:3000/api/todos>' from origin '<http://localhost:8000>' has been **blocked by CORS policy**...

O que os Alunos Aprenderam

Eles acabaram de descobrir o CORS (Cross-Origin Resource Sharing). O navegador, por segurança, impediu que o localhost:8000 (o "Frontend") fizesse uma requisição para o localhost:3000 (o "Backend") porque eles são "origens" (portas) diferentes.

Agora, eles têm a motivação para corrigir isso.