Executando verificação de segurança...
26

Seu frontend não quebra por acaso, ele quebra por suposição


Recentemente, lendo Software Engineering at Google, me deparei com um conceito que me fez pensar bastante sobre como escrevemos código: a Lei de Hyrum. Ela diz algo mais ou menos assim: Quanto mais sistemas consumirem sua API, qualquer comportamento observável de um sistema será dependido por alguém, mesmo que não seja algo explicitamente documentado.

No livro, o foco é mostrar como o Google evita problemas ao criar contratos claros entre equipes e APIs. Mas, como um bom pintor de botões (ou desenvolvedor front-end, se preferir), caiu a ficha sobre a importância de sempre escrever código que dependa de contratos explícitos, e não de suposições sobre como APIs, bibliotecas ou quaisquer componentes de terceiros vão se comportar.

Reuni aqui algumas das armadilhas mais comuns ao codificar UIs complexas, pode soar como bom senso pra quem já tem uns bugs de experiência, mas é sempre bom relembrar.

1 - Utilizar dados diretamente de uma camada externa (e confiar demais nisso)

❌ Bomba relógio

const fetchData = async () => {
  const res = await fetch("/api/products");
  return res.json();
};

const data = await fetchData();
console.log(data.price); // Pode quebrar se a API mudar (spoiler: ela vai!)

Aqui o código assume implicitamente que a API sempre retornará um objeto com price.
Se a resposta mudar de formato, o frontend quebra silenciosamente, seu usuário vai pro site do concorrente e seu chefe te manda um whats sábado a noite.

✅ Forma explícita

A boa prática é criar uma camada intermediária de adaptação (parser, adapter ou normalizer), um módulo responsável por traduzir a resposta da API para o formato que o frontend espera.
Assim, o contrato entre “API externa” e “UI” fica claro e controlado.

// Define o formato que o frontend espera
interface Product {
  id: string;
  name: string;
  price: number;
}

// Função que lida com a incerteza da API
const parseProducts = (data: unknown): Product[] => {
  if (!Array.isArray(data)) {
    throw new Error("Formato inesperado da resposta da API");
  }

  // Valida e adapta se necessário
  return data.map((item) => ({
    id: String(item.id),
    name: String(item.name ?? "Sem nome"),
    price: Number(item.price ?? 0),
  }));
};

// Função responsável por buscar e normalizar os dados
const fetchProducts = async (): Promise<Product[]> => {
  const res = await fetch("/api/products");
  const raw = await res.json();
  return parseProducts(raw);
};

A função parseProducts traduz o comportamento externo para o interno, ela isola possíveis mudanças da API e garante que o resto do front sempre receba dados no formato esperado.
Essa camada é a garantia de uma noite de sono tranquila, ela converte o mundo incerto da API em algo previsível, seguro e documentado.

2 - Tratar apenas o cenário feliz

❌ Bomba relógio

Supõe que algo sempre retorne um produto válido

const ProductPrice = () => {
  const product = useProduct();

  // Uso direto sem checar
  return <div>Preço: R$ {product.price}</div>;
};

Se useProduct() mudar de comportamento (por exemplo, passar a retornar null enquanto carrega ou undefined em erro), o componente quebra silenciosamente em produção.

Esse é o tipo de dependência implícita que parece inofensiva, até que uma atualização de biblioteca ou API mude um detalhe.

✅ Forma explícita (sem confiar nem na própria sombra)

const ProductPrice = () => {
  const { product, loading } = useProduct();

  if (loading) return <p>Carregando...</p>;
  if (!product) return <p>Produto não encontrado</p>;

  return <div>Preço: R$ {product.price.toFixed(2)}</div>;
};

Mesmo que a biblioteca mude internamente, o front sabe exatamente o que esperar e pode tratar cada caso com segurança.

Ao montar a camada de visualização, nunca presuma que os dados de uma API serão sempre válidos. Se esforce pra identificar os possíveis ponto de falha e, caso necessário, falhe seu front graciosamente.

3 - Encapsular componentes de bibliotecas externas

❌ Bomba relógio

import { Button } from "biblioteca-da-moda-2025";

export const ProductActions = () => (
  <div>
    <Button onClick={handleBuy}>Comprar</Button>
    <Button onClick={handleAddToCart}>Adicionar ao carrinho</Button>
  </div>
);

Aqui, o frontend depende diretamente da biblioteca biblioteca-da-moda-2025.
Se amanhã a biblioteca mudar a API (por exemplo, trocar onClick por onPress ou alterar o estilo padrão), você precisará alterar dezenas de arquivos espalhados pelo código.

Além disso, o contrato visual e funcional do botão não está sob seu controle, pertence à lib.

✅ Forma explícita

Encapsule o comportamento e a aparência esperada no seu próprio componente, e use apenas ele em toda sua aplicaçâo.

import { Button as LibButton } from "biblioteca-da-moda-2025";

interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary";
}

export const Button = ({ label, onClick, variant = "primary" }: ButtonProps) => {
  return (
    <LibButton
      onClick={onClick}
      className={`my-button ${variant}`}
    >
      {label}
    </LibButton>
  );
};

Agora, até um trabalho moroso como passar a usar a biblioteca-da-moda-2026, basta alterar um único componente.

Quando uma biblioteca oferece um componente para resolver um problema (botão, modal, input etc.), use-a como dependência interna, não como parte pública da sua aplicação.
Crie o seu próprio componente que encapsula o comportamento, isso reduz o acoplamento, facilita a manutenção e torna futuras substituições quase triviais.

Nenhum outro arquivo do projeto precisa saber que existe uma dependência externa.

Conclusão

Claro que o front não pode (nem deve) absorver toda a responsabilidade do mundo, ele é só uma peça do sistema.
Mas pode ser defensivo: validar o que recebe, explicitar o que espera e nunca confiar cegamente em nada que venha de fora.

No fim das contas, quanto menos o seu código depender do que parece funcionar, e mais do que foi claramente acordado, mais livre você é pra evoluir o sistema sem medo de quebrar o resto.

No fim das contas, explícito pode dar trabalho, mas implícito dá plantão.

Carregando publicação patrocinada...
4

sexta 18:99 do segundo tempo tu ja tava quase fechando o note ai o site começa a quebrar do nada e o cliente mandando print no whatsapp dizendo q o botão de compra sumiu e o checkout n funciona mais tu entra no inspecionar lelemento e ve q o tal lib-da-moda-2025.min.js q vinha da cdn jsdelivr ta dando 404 pq os caras tiraram a versão antiga do ar e agora a versao nova mudou tudo trocou onClick por handleClick e ainda mudou o css padrao o front inteiro ta desalinhado e sem estilo seco seco o gerente fala q precisa resolver rapido pq o site ta em campanha e ta saindo no instagram com link ativo pessoas estao chorando

oq vc tem q fazer?

3
-1
2
0
2
0