SANAKA
Saṃvit e Nandinī estão diante do balcão da padaria cósmica enquanto Śambhu e Naṭarāja discutem e cozinham.
← Voltar ao catálogo da Matrix

Matrix on-line · Laboratório 06

A padaria de Saṃvit

Consulte o cardápio de Saṃvit, faça um pedido e veja a resposta. Depois experimente repetir um pagamento fictício.

Experimentar

Faça um pedido com Saṃvit

Esta padaria usa produtos e créditos imaginários. Tudo acontece nesta página.

Etapa 1 de 4

Consultar cardápio

Peça o cardápio. Depois receba a resposta para conhecer os produtos, preços e estoque.

Pede os produtos sem mudar estoque ou criar pedidos. No código, esta leitura usa GET.

O que aconteceu?

Escolha a ação desta etapa. O resultado aparece aqui depois do seu clique.

Ver explicação técnica e código desta passagem

A simulação mantém produtos, pedidos e pagamentos em memória. GET lê; POST pode criar registros.

TypeScriptbakery-api.ts
Contratos tipados
/** Contratos do exemplo. O servidor ainda valida entradas: tipos TS não protegem uma API real. */
export type OrderBody = {
  readonly productId: string;
  readonly quantity: number;
  readonly delivery: boolean;
};
export type PaymentBody = { readonly orderId: string; readonly token: 'demo-token' };
export interface BakeryRequest {
  readonly method: 'GET' | 'POST';
  readonly path: string;
  readonly body?: Readonly<Record<string, string | number | boolean>>;
  // Aqui a chave representa um header de requisição, não um campo do pagamento.
  readonly idempotencyKey?: string;
}
export interface BakeryResponse {
  readonly status: 200 | 201 | 400 | 404 | 409 | 500;
  readonly body: unknown;
  readonly headers?: Readonly<Record<string, string>>;
}
Inspecionar os registros antes e depois

Estes registros mostram a simulação em cada momento. Rever uma passagem muda o estado observado; agir a partir dela substitui o caminho que vinha depois.

Estado anterior

{
  "products": [
    {
      "id": "bread",
      "priceCredits": 3,
      "stock": 8
    },
    {
      "id": "cake",
      "priceCredits": 5,
      "stock": 5
    }
  ],
  "orders": [],
  "payments": [],
  "paymentKeys": {},
  "request": null,
  "response": null,
  "phase": "idle",
  "failure": "none"
}

Estado observado

{
  "products": [
    {
      "id": "bread",
      "priceCredits": 3,
      "stock": 8
    },
    {
      "id": "cake",
      "priceCredits": 5,
      "stock": 5
    }
  ],
  "orders": [],
  "payments": [],
  "paymentKeys": {},
  "request": null,
  "response": null,
  "phase": "idle",
  "failure": "none"
}
Experimentar outras respostas (opcional)

Escolha como o próximo envio será respondido: normalmente, com erro do servidor ou com falha de rede. A seleção não envia nada sozinha.

Cenário selecionado: Fluxo normal

Envia quantidade 0 de propósito para observar a rejeição pelo servidor.

Pede um resumo que junta cardápio e pedidos recentes. Veja o formato da resposta no detalhe técnico.

Limpa os pedidos e pagamentos e recomeça sem pão no estoque. Crie um pedido de pão para observar o conflito.

Consulte o cardápio e clique em “Receber resposta”.

Código em movimento

Se quiser ir além

Trecho 1 de 4
Consultar as funções e os arquivos

Funções completas deste laboratório, extraídas dos arquivos reais. A explicação da ação atual está junto do experimento.

TypeScriptbakery-api.ts
Contratos tipados
/** Contratos do exemplo. O servidor ainda valida entradas: tipos TS não protegem uma API real. */
export type OrderBody = {
  readonly productId: string;
  readonly quantity: number;
  readonly delivery: boolean;
};
export type PaymentBody = { readonly orderId: string; readonly token: 'demo-token' };
export interface BakeryRequest {
  readonly method: 'GET' | 'POST';
  readonly path: string;
  readonly body?: Readonly<Record<string, string | number | boolean>>;
  // Aqui a chave representa um header de requisição, não um campo do pagamento.
  readonly idempotencyKey?: string;
}
export interface BakeryResponse {
  readonly status: 200 | 201 | 400 | 404 | 409 | 500;
  readonly body: unknown;
  readonly headers?: Readonly<Record<string, string>>;
}
Contratos tipados

Os tipos descrevem pedidos e respostas; a validação do servidor continua necessária.

Onde estudar estes arquivos
Rever os conceitos
Um pedido precisa dizer o que quer

Em palavras simples

Dizer “quero pão” não informa quantos nem se haverá entrega. Um combinado claro ajuda a conferir se o pedido pode ser atendido.

O conceito técnico

O contrato define método, caminho, corpo e resposta. GET consulta recursos; POST solicita processamento ou criação. JSON é um formato de dados, não sinônimo de REST. Tipos TypeScript não substituem validação no servidor.

Cada camada responde por uma parte

Em palavras simples

Saṃvit escolhe, Nandinī verifica e Mors confirma. Se tudo for responsabilidade da mesma pessoa, fica difícil localizar um erro.

O conceito técnico

A interface coleta entradas; acesso a dados prepara comunicação; o servidor valida e processa; a resposta atualiza a tela. Um BFF pode adaptar contratos ou agregar serviços para um frontend específico, mas não é obrigatório.

Repetir a intenção sem repetir o efeito

Em palavras simples

Se Saṃvit não ouviu a confirmação, repetir “pague este pedido” não deveria virar duas cobranças. Identificar a mesma intenção ajuda a reconhecer a repetição.

O conceito técnico

Idempotência diz respeito ao efeito de repetir uma operação. POST não é idempotente por definição; um contrato pode adicionar essa propriedade com chaves e armazenamento consistente. Não é a mesma coisa que desabilitar o botão.

Testar exemplos

Confira o que aprendeu

Abrir exemplos de verificação

Este botão roda exemplos prontos e compara os resultados. Ele não altera sua experiência.

Explorar

Continue explorando

E se o pedido vier vazio?

O servidor devolve 400 sem alterar estoque. Teste createBakeryOrder com body ausente; uma API real não deve confiar no formulário do cliente.

E se repetir o pagamento?

Crie um pedido, pague e repita o último POST. Com a mesma chave, permanece um registro; sem chave, o modo didaticamente inseguro duplica. Repetir a criação de pedido também cria outro pedido, se houver estoque.

E se a resposta falhar?

Escolha 500 ou rede antes da requisição. No primeiro caso existe resposta HTTP; no segundo não. Voltar no histórico só inspeciona memória local, nunca desfaz um serviço real.

Onde acrescentar uma nova regra de compra?

Na validação do domínio, com testes para sucesso e rejeição. Uma mudança de contrato exige revisar tipos, interface, resposta e traduções. Não esconda a regra apenas no HTML.

Compare com a chamada HTTP real da NASA →