Skip to content

Instantly share code, notes, and snippets.

@wmonteiro-ai
Created September 6, 2025 22:12
Show Gist options
  • Select an option

  • Save wmonteiro-ai/b65e07d820fe571f1ed484bd10c6f55b to your computer and use it in GitHub Desktop.

Select an option

Save wmonteiro-ai/b65e07d820fe571f1ed484bd10c6f55b to your computer and use it in GitHub Desktop.
Simulador de API
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Guia de Estudos e Simulador de APIs</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700;800;900&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #F8F8F8;
}
/* Cores da Identidade Visual */
.bg-brand-primary { background-color: #8a0538; }
.text-brand-primary { color: #8a0538; }
.bg-brand-request { background-color: #ff0040; }
.text-brand-request { color: #ff0040; }
.border-brand-request { border-color: #ff0040; }
.bg-brand-response { background-color: #9654ff; }
.text-brand-response { color: #9654ff; }
.border-brand-response { border-color: #9654ff; }
/* Estilos de Fonte */
.title-main { font-weight: 900; text-transform: uppercase; }
.title-section { font-weight: 800; text-transform: uppercase; }
.info-highlight { font-weight: 400; text-transform: uppercase; }
.text-body { font-weight: 400; }
/* Componentes da UI */
.code-inline { background-color: #e2e8f0; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.9em; }
.form-input { width: 100%; background-color: #f1f5f9; padding: 0.75rem; border-radius: 0.5rem; border: 2px solid transparent; transition: border-color 0.3s; }
.form-input:focus { outline: none; border-color: #ff0040; }
.code-area { font-family: monospace; font-size: 0.875rem; line-height: 1.5; background-color: #f1f5f9; padding: 1rem; border-radius: 0.5rem; white-space: pre-wrap; word-break: break-all; min-height: 120px; }
#send-request-btn { transition: all 0.2s ease-in-out; }
#send-request-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.15); }
.status-code { padding: 4px 12px; border-radius: 9999px; font-weight: bold; color: white; }
.status-200 { background-color: #22c55e; } .status-201 { background-color: #16a34a; } .status-400 { background-color: #f97316; } .status-404 { background-color: #ef4444; } .status-500 { background-color: #713f12; }
/* Animação do Fluxo */
.packet, .packet-response { opacity: 0; }
.animate-request .packet { animation: move-packet 0.8s ease-in-out forwards; }
.animate-response .packet-response { animation: move-packet-response 0.8s ease-in-out 0.9s forwards; }
@keyframes move-packet {
0% { transform: translateX(0); opacity: 1; }
99% { transform: translateX(290px); opacity: 1; }
100% { transform: translateX(290px); opacity: 0; }
}
@keyframes move-packet-response {
0% { transform: translateX(0); opacity: 1; }
99% { transform: translateX(-290px); opacity: 1; }
100% { transform: translateX(-290px); opacity: 0; }
}
/* Roadmap */
.roadmap-container {
position: relative;
padding-left: 50px;
}
.roadmap-line {
position: absolute;
left: 24px;
top: 20px;
bottom: 20px;
width: 4px;
background-color: #e2e8f0;
z-index: 1;
}
.roadmap-category {
position: relative;
margin-bottom: 2rem;
}
.roadmap-category h4 {
position: sticky;
top: 0;
background: #F8F8F8;
padding: 8px 0;
z-index: 10;
}
.roadmap-item {
position: relative;
padding: 1rem;
margin-left: 1rem;
margin-bottom: 1rem;
background-color: white;
border-radius: 0.5rem;
border: 1px solid #e2e8f0;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
z-index: 5;
}
.roadmap-item::before {
content: '';
position: absolute;
left: -29px;
top: 24px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #9654ff;
border: 4px solid #F8F8F8;
z-index: 6;
}
.roadmap-item.book::before {
background-color: #f59e0b; /* amber-500 */
}
.roadmap-item summary {
cursor: pointer;
font-size: 1.1rem;
font-weight: 700;
color: #334155;
outline: none;
display: flex;
align-items: center;
gap: 0.5rem;
}
.roadmap-item[open] summary {
color: #8a0538;
}
.roadmap-item .content {
margin-top: 1rem;
}
.resource-link {
display: flex;
align-items: center;
gap: 0.5rem;
color: #1d4ed8;
text-decoration: none;
}
.resource-link:hover {
text-decoration: underline;
}
.resource-link svg {
width: 1rem;
height: 1rem;
flex-shrink: 0;
}
</style>
</head>
<body class="text-gray-800">
<div class="container mx-auto p-4 md:p-8">
<header class="text-center mb-10">
<h1 class="title-main text-3xl md:text-5xl mb-2 text-brand-primary">Guia de Estudos e Simulador de APIs</h1>
<h2 class="text-body text-xl md:text-2xl text-brand-response">Entendendo a Comunicação HTTP</h2>
</header>
<section class="text-center mb-10 p-6 bg-gray-100 rounded-2xl border border-gray-200">
<h4 class="info-highlight text-lg text-gray-700 mb-2">POR QUE SABER DISSO?</h4>
<p class="text-body text-gray-600 max-w-4xl mx-auto">
HTTP é o protocolo que a web usa para "conversar". Toda vez que você acessa um site ou usa um aplicativo que busca dados na nuvem, uma requisição HTTP está sendo feita. APIs são "portas" em um servidor que entendem essa conversa. Dominar os fundamentos do HTTP permite a você construir ou integrar qualquer sistema na web, pois você aprende a fazer os "pedidos" corretos e a entender as "respostas" recebidas.
</p>
</section>
<section class="mb-10" id="flow-container">
<h3 class="title-section text-2xl text-center mb-6 text-brand-primary">Fluxo da Comunicação API</h3>
<div class="bg-white shadow-lg p-6 rounded-2xl border-2 border-gray-200/50 flex justify-center items-center overflow-hidden">
<svg width="100%" height="120" viewBox="0 0 600 120">
<!-- Client -->
<rect x="10" y="30" width="120" height="60" rx="10" fill="#ff0040" />
<text x="70" y="65" font-family="Poppins" font-weight="bold" font-size="16" fill="white" text-anchor="middle">CLIENTE</text>
<!-- Server -->
<rect x="470" y="30" width="120" height="60" rx="10" fill="#9654ff" />
<text x="530" y="65" font-family="Poppins" font-weight="bold" font-size="16" fill="white" text-anchor="middle">SERVIDOR</text>
<!-- Request Path -->
<path d="M 130 60 L 470 60" stroke="#ff0040" stroke-width="2" stroke-dasharray="5 5" />
<g id="request-packets">
<circle cx="140" cy="60" r="6" fill="#ff0040" class="packet" />
<circle cx="140" cy="60" r="6" fill="#ff0040" class="packet" style="animation-delay: 0.15s;" />
<circle cx="140" cy="60" r="6" fill="#ff0040" class="packet" style="animation-delay: 0.3s;" />
</g>
<text x="300" y="50" font-family="Poppins" font-size="14" fill="#ff0040" text-anchor="middle">Requisição ➔</text>
<!-- Response Path -->
<path d="M 470 80 L 130 80" stroke="#9654ff" stroke-width="2" stroke-dasharray="5 5" />
<g id="response-packets">
<circle cx="460" cy="80" r="6" fill="#9654ff" class="packet-response" />
<circle cx="460" cy="80" r="6" fill="#9654ff" class="packet-response" style="animation-delay: 0.15s;" />
<circle cx="460" cy="80" r="6" fill="#9654ff" class="packet-response" style="animation-delay: 0.3s;" />
</g>
<text x="300" y="95" font-family="Poppins" font-size="14" fill="#9654ff" text-anchor="middle">⬅ Resposta</text>
</svg>
</div>
</section>
<main class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div class="bg-white shadow-xl p-6 rounded-2xl border-2 border-brand-request/30">
<h3 class="title-section text-2xl text-brand-request mb-6">CLIENTE (Sua Requisição)</h3>
<div class="flex gap-4 mb-4">
<div class="w-1/3">
<label for="http-method" class="info-highlight text-sm text-gray-500 mb-1 block">MÉTODO</label>
<select id="http-method" class="form-input">
<option value="GET">GET</option> <option value="POST">POST</option> <option value="PUT">PUT</option> <option value="DELETE">DELETE</option>
</select>
</div>
<div class="w-2/3">
<label for="url-select" class="info-highlight text-sm text-gray-500 mb-1 block">URL (ENDPOINT)</label>
<select id="url-select" class="form-input">
<option value="/usuarios">/usuarios (Listar todos)</option>
<option value="/usuarios/1">/usuarios/1 (Buscar específico)</option>
<option value="/produtos">/produtos (Listar todos)</option>
<option value="/usuarios/99">/usuarios/99 (Buscar inexistente)</option>
</select>
</div>
</div>
<div class="mb-4">
<label for="headers-input" class="info-highlight text-sm text-gray-500 mb-1 block">HEADERS (Cabeçalhos)</label>
<textarea id="headers-input" class="form-input font-mono text-sm" rows="3">Content-Type: application/json</textarea>
</div>
<div class="mb-6" id="body-container">
<label for="body-input" class="info-highlight text-sm text-gray-500 mb-1 block">BODY (Corpo)</label>
<textarea id="body-input" class="form-input font-mono text-sm" rows="5"></textarea>
</div>
<button id="send-request-btn" class="w-full bg-brand-request text-white font-bold py-4 px-6 rounded-lg uppercase text-base">Enviar Requisição</button>
</div>
<div class="bg-white shadow-xl p-6 rounded-2xl border-2 border-brand-response/30">
<h3 class="title-section text-2xl text-brand-response mb-6">SERVIDOR (A Resposta)</h3>
<div class="mb-4">
<label class="info-highlight text-sm text-gray-500 mb-2 block">STATUS CODE</label>
<div id="status-code-output" class="font-bold text-lg">...</div>
</div>
<div class="mb-4">
<label class="info-highlight text-sm text-gray-500 mb-2 block">HEADERS DA RESPOSTA</label>
<pre id="response-headers-output" class="code-area">...</pre>
</div>
<div>
<label class="info-highlight text-sm text-gray-500 mb-2 block">BODY DA RESPOSTA</label>
<pre id="response-body-output" class="code-area">...</pre>
</div>
<div id="analysis-output" class="mt-6 p-4 bg-gray-50 border-l-4 rounded-r-lg"></div>
</div>
</main>
<section class="mt-12 bg-white rounded-2xl shadow-lg p-6">
<h3 class="title-section text-2xl text-center mb-6 text-brand-primary">Roadmap de Estudos de APIs</h3>
<div class="roadmap-container">
<div class="roadmap-line"></div>
<!-- CATEGORIA: FUNDAMENTOS DA WEB -->
<div class="roadmap-category">
<h4 class="title-section text-lg text-brand-primary">1. Fundamentos da Web</h4>
<details class="roadmap-item">
<summary>Como a Internet Funciona</summary>
<div class="content space-y-4">
<p>A internet é uma rede global de computadores interconectados que se comunicam usando protocolos padronizados, principalmente o TCP/IP. Quando você requisita uma página web, seu dispositivo envia um pacote de dados através do seu provedor (ISP) para um servidor DNS, que traduz o domínio do site em um endereço IP. O pacote é então roteado através de várias redes até o servidor de destino, que processa o pedido e envia a resposta.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://www.youtube.com/watch?v=x3c1ih2NJEg" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.647c1.295.748 1.295 2.536 0 3.284L7.279 20.99c-1.25.72-2.779-.217-2.779-1.643V5.653z" clip-rule="evenodd" /></svg>
<span>Como a Internet funciona? (em 8 minutos)</span>
</a></li>
<li><a href="https://cs.fyi/guide/how-does-internet-work" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>How Does the Internet Work? - Computer Science Wiki</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item">
<summary>DNS (Sistema de Nomes de Domínio)</summary>
<div class="content space-y-4">
<p>O DNS (Domain Name System) atua como uma "lista telefônica" da internet, traduzindo nomes de domínio legíveis por humanos (como <code class="code-inline">www.google.com</code>) em endereços IP numéricos (como <code class="code-inline">142.250.218.68</code>) que os computadores usam para se localizar.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://howdns.works/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>How DNS Works (em quadrinhos)</span>
</a></li>
<li><a href="https://www.youtube.com/watch?v=Wj0od2ag5sk" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.647c1.295.748 1.295 2.536 0 3.284L7.279 20.99c-1.25.72-2.779-.217-2.779-1.643V5.653z" clip-rule="evenodd" /></svg>
<span>DNS and How does it Work?</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item book">
<summary>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"><path d="M11.25 4.533A9.707 9.707 0 006 3a9.735 9.735 0 00-3.25.555.75.75 0 00-.5.707v14.25a.75.75 0 001 .707A9.735 9.735 0 006 18a9.707 9.707 0 005.25 1.533.75.75 0 00.5-.707V5.24a.75.75 0 00-.5-.707zM12.75 4.533A9.707 9.707 0 0118 3a9.735 9.735 0 013.25.555.75.75 0 01.5.707v14.25a.75.75 0 01-1 .707A9.735 9.735 0 0118 18a9.707 9.707 0 01-5.25 1.533.75.75 0 01-.5-.707V5.24a.75.75 0 01.5-.707z" /></svg>
Livros Renomados
</summary>
<div class="content space-y-4">
<p>Para uma base sólida em redes, estes livros são considerados clássicos da área.</p>
<ul class="space-y-2">
<li><strong>Redes de Computadores e a Internet: Uma Abordagem Top-Down</strong> (Kurose, Ross) - Excelente por explicar a internet camada por camada, do aplicativo ao físico.</li>
<li><strong>Redes de Computadores</strong> (Tanenbaum, Wetherall) - Uma obra de referência completa, cobrindo todos os aspectos teóricos e práticos de redes.</li>
</ul>
</div>
</details>
</div>
<!-- CATEGORIA: PROTOCOLO HTTP -->
<div class="roadmap-category">
<h4 class="title-section text-lg text-brand-primary">2. Protocolo HTTP</h4>
<details class="roadmap-item">
<summary>O que é HTTP?</summary>
<div class="content space-y-4">
<p>HTTP (Hypertext Transfer Protocol) é o protocolo usado para transmitir dados na web. Ele define como as mensagens são formatadas e transmitidas, e como servidores e navegadores devem responder aos comandos. Opera em um modelo de requisição-resposta.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Overview" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>Visão Geral do HTTP - MDN</span>
</a></li>
<li><a href="https://www.youtube.com/watch?v=j9QmMEWmcfo" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.647c1.295.748 1.295 2.536 0 3.284L7.279 20.99c-1.25.72-2.779-.217-2.779-1.643V5.653z" clip-rule="evenodd" /></svg>
<span>SSL, TLS, HTTPS Explained</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item">
<summary>Métodos HTTP, Status Codes, Headers e Body</summary>
<div class="content space-y-4">
<p>Esta é a anatomia de uma "conversa" HTTP. <strong>Métodos</strong> (ou "verbos") definem a ação (<code class="code-inline">GET</code>, <code class="code-inline">POST</code>). <strong>Status Codes</strong> indicam o resultado (200 OK, 404 Not Found). <strong>Headers</strong> transportam metadados. O <strong>Body</strong> contém os dados.</p>
</div>
</details>
</div>
<!-- CATEGORIA: DESIGN DE APIS -->
<div class="roadmap-category">
<h4 class="title-section text-lg text-brand-primary">3. Design de APIs</h4>
<details class="roadmap-item">
<summary>Estilos de API (REST, GraphQL, gRPC, etc)</summary>
<div class="content space-y-4">
<p>APIs podem ser estruturadas em vários estilos. Os mais comuns são <strong>REST</strong> (padrão da web, baseado em recursos), <strong>GraphQL</strong> (permite ao cliente pedir exatamente o que precisa), <strong>SOAP</strong> (protocolo mais antigo e rígido) e <strong>gRPC</strong> (alta performance para comunicação entre microsserviços).</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://www.youtube.com/watch?v=4vLxWqE94l4" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.647c1.295.748 1.295 2.536 0 3.284L7.279 20.99c-1.25.72-2.779-.217-2.779-1.643V5.653z" clip-rule="evenodd" /></svg>
<span>Top API Styles</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item">
<summary>Autenticação e Autorização</summary>
<div class="content space-y-4">
<p><strong>Autenticação</strong> confirma *quem* você é (ex: login e senha, API Key). <strong>Autorização</strong> define *o que* você pode fazer após ser autenticado (ex: usuário comum vs. administrador). Padrões comuns incluem Autenticação Básica, API Keys, OAuth 2.0 e JWT.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://www.postman.com/api-platform/api-authentication/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>API Authentication - Postman</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item book">
<summary>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"><path d="M11.25 4.533A9.707 9.707 0 006 3a9.735 9.735 0 00-3.25.555.75.75 0 00-.5.707v14.25a.75.75 0 001 .707A9.735 9.735 0 006 18a9.707 9.707 0 005.25 1.533.75.75 0 00.5-.707V5.24a.75.75 0 00-.5-.707zM12.75 4.533A9.707 9.707 0 0118 3a9.735 9.735 0 013.25.555.75.75 0 01.5.707v14.25a.75.75 0 01-1 .707A9.735 9.735 0 0118 18a9.707 9.707 0 01-5.25 1.533.75.75 0 01-.5-.707V5.24a.75.75 0 01.5-.707z" /></svg>
Livros Renomados
</summary>
<div class="content space-y-4">
<p>Para aprender a projetar APIs robustas, elegantes e fáceis de usar.</p>
<ul class="space-y-2">
<li><strong>Designing Web APIs</strong> (Amir Shevat) - Um guia prático e direto para o design de APIs RESTful, focado na experiência do desenvolvedor.</li>
<li><strong>The Design of Web APIs</strong> (Arnaud Lauret) - Aborda o design de APIs como um produto, cobrindo todo o ciclo de vida com exemplos práticos.</li>
<li><strong>APIs: A Strategy Guide</strong> (Daniel Jacobson, Greg Brail, Dan Woods) - Focado na estratégia de negócio por trás das APIs, essencial para arquitetos e líderes técnicos.</li>
</ul>
</div>
</details>
</div>
<!-- CATEGORIA: TÓPICOS AVANÇADOS -->
<div class="roadmap-category">
<h4 class="title-section text-lg text-brand-primary">4. Tópicos Avançados e Boas Práticas</h4>
<details class="roadmap-item">
<summary>Segurança</summary>
<div class="content space-y-4">
<p>Abrange práticas para proteger APIs contra ataques, como validação de entradas, prevenção contra injeção de código, e o uso de padrões de segurança como os definidos pelo OWASP API Security Top 10.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://owasp.org/API-Security/editions/2023/en/0x00-toc/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>OWASP API Security Top 10</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item" open>
<summary>Performance e Cache</summary>
<div class="content space-y-4">
<p>Envolve otimizar a velocidade e eficiência da API. Tópicos incluem o monitoramento de <strong>métricas</strong> (latência, throughput), <strong>testes de performance</strong> para simular carga e o uso de <strong>estratégias de cache</strong> para armazenar dados temporariamente e reduzir a carga no servidor.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://www.youtube.com/watch?v=dGAgxozNWFE" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M4.5 5.653c0-1.426 1.529-2.33 2.779-1.643l11.54 6.647c1.295.748 1.295 2.536 0 3.284L7.279 20.99c-1.25.72-2.779-.217-2.779-1.643V5.653z" clip-rule="evenodd" /></svg>
<span>Sistemas de Cache que Todo Desenvolvedor Deveria Saber</span>
</a></li>
<li><a href="https://testsigma.com/blog/api-performance-testing/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>Teste de Performance de APIs: Guia Passo a Passo</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item">
<summary>Testes (Funcional e de Contrato)</summary>
<div class="content space-y-4">
<p><strong>Testes Funcionais</strong> validam se os endpoints e a lógica da API funcionam como esperado. <strong>Testes de Contrato</strong> garantem que a API e seus consumidores cumpram o "contrato" acordado, prevenindo quebras de integração.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://testsigma.com/blog/api-contract-testing/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path fill-rule="evenodd" d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0016.5 9h-1.875a.375.375 0 01-.375-.375V6.75A3.75 3.75 0 0010.5 3h-4.875c0-.023.002-.046.002-.069a1.875 1.875 0 00-1.875-1.875H5.625zM10.5 6A2.25 2.25 0 008.25 8.25v12A2.25 2.25 0 0010.5 22.5h7.5A2.25 2.25 0 0020.25 20.25V12.75a.375.375 0 01.375-.375H22.5a2.25 2.25 0 002.25-2.25V7.5a2.25 2.25 0 00-2.25-2.25h-9z" clip-rule="evenodd" /></svg>
<span>Guia Completo de Testes de Contrato</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item">
<summary>Documentação</summary>
<div class="content space-y-4">
<p>Uma documentação clara é crucial para a adoção de uma API. Ferramentas como <strong>Swagger (OpenAPI)</strong> ajudam a criar documentações interativas e fáceis de entender.</p>
<div>
<h5 class="font-bold mb-2">Recursos para Estudo:</h5>
<ul class="space-y-2">
<li><a href="https://swagger.io/" target="_blank" class="resource-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" /></svg>
<span>Swagger - Ferramentas de API</span>
</a></li>
</ul>
</div>
</div>
</details>
<details class="roadmap-item book">
<summary>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"><path d="M11.25 4.533A9.707 9.707 0 006 3a9.735 9.735 0 00-3.25.555.75.75 0 00-.5.707v14.25a.75.75 0 001 .707A9.735 9.735 0 006 18a9.707 9.707 0 005.25 1.533.75.75 0 00.5-.707V5.24a.75.75 0 00-.5-.707zM12.75 4.533A9.707 9.707 0 0118 3a9.735 9.735 0 013.25.555.75.75 0 01.5.707v14.25a.75.75 0 01-1 .707A9.735 9.735 0 0118 18a9.707 9.707 0 01-5.25 1.533.75.75 0 01-.5-.707V5.24a.75.75 0 01.5-.707z" /></svg>
Livros Renomados
</summary>
<div class="content space-y-4">
<p>Leituras para aprofundar em tópicos avançados e arquitetura de software.</p>
<ul class="space-y-2">
<li><strong>Building Microservices</strong> (Sam Newman) - Essencial para entender a arquitetura por trás de muitas APIs modernas, com foco em resiliência e escalabilidade.</li>
<li><strong>Designing Data-Intensive Applications</strong> (Martin Kleppmann) - Uma obra-prima sobre os fundamentos de sistemas de dados, crucial para projetar APIs performáticas e confiáveis.</li>
</ul>
</div>
</details>
</div>
</div>
</section>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const methodSelect = document.getElementById('http-method');
const urlSelect = document.getElementById('url-select');
const headersInput = document.getElementById('headers-input');
const bodyInput = document.getElementById('body-input');
const bodyContainer = document.getElementById('body-container');
const sendBtn = document.getElementById('send-request-btn');
const statusCodeOutput = document.getElementById('status-code-output');
const responseHeadersOutput = document.getElementById('response-headers-output');
const responseBodyOutput = document.getElementById('response-body-output');
const analysisOutput = document.getElementById('analysis-output');
const flowContainer = document.getElementById('flow-container');
let db = {
usuarios: [ { id: 1, nome: 'Ana Silva', email: '[email protected]' }, { id: 2, nome: 'Bruno Costa', email: '[email protected]' }, { id: 3, nome: 'Carlos Souza', email: '[email protected]' } ],
produtos: [ { id: 101, nome: 'Notebook Gamer', preco: 4500.00 }, { id: 102, nome: 'Mouse sem fio', preco: 120.50 } ]
};
let nextUserId = 4;
let nextProductId = 103;
function toggleBodyInput() {
const method = methodSelect.value;
bodyContainer.style.display = (method === 'POST' || method === 'PUT') ? 'block' : 'none';
}
function updateBodyPlaceholder() {
const method = methodSelect.value;
const url = urlSelect.value;
const resource = url.split('/')[1];
let placeholderBody = {};
if (method === 'POST') {
if (resource === 'usuarios') {
placeholderBody = { nome: "Novo Usuário", email: "[email protected]" };
} else if (resource === 'produtos') {
placeholderBody = { nome: "Novo Produto", preco: 99.99 };
}
} else if (method === 'PUT') {
if (resource === 'usuarios') {
placeholderBody = { email: "[email protected]" };
} else if (resource === 'produtos') {
placeholderBody = { preco: 150.00 };
}
} else {
bodyInput.value = '';
return;
}
bodyInput.value = JSON.stringify(placeholderBody, null, 2);
}
function updateResponseUI(status, statusText, headers, body, analysis) {
const statusClass = `status-${Math.floor(status / 100) * 100}`;
statusCodeOutput.innerHTML = `<span class="status-code ${statusClass}">${status} ${statusText}</span>`;
responseHeadersOutput.textContent = JSON.stringify(headers, null, 2);
responseBodyOutput.textContent = JSON.stringify(body, null, 2);
analysisOutput.innerHTML = `<p class="info-highlight text-sm text-brand-response">DICA DO PROFESSOR</p><p class="text-body text-sm text-gray-700 mt-1">${analysis}</p>`;
}
function animateFlow() {
flowContainer.classList.remove('animate-request', 'animate-response');
void flowContainer.offsetWidth;
flowContainer.classList.add('animate-request', 'animate-response');
}
function handleRequest() {
animateFlow();
const method = methodSelect.value;
const path = urlSelect.value;
const body = bodyInput.value;
const parts = path.split('/').filter(p => p);
const resource = parts[0];
const id = parts[1] ? parseInt(parts[1], 10) : null;
let status, statusText, headers, responseBody, analysis;
headers = { 'Content-Type': 'application/json', 'Server': 'Simulador-API/1.0', 'Date': new Date().toUTCString() };
// Atraso para a resposta aparecer depois da animação
setTimeout(() => {
if (!db[resource]) {
status = 404; statusText = 'Not Found';
responseBody = { erro: `O recurso '${resource}' não existe neste servidor.` };
analysis = `<strong>Status 404 Not Found:</strong> O servidor não encontrou o tipo de recurso solicitado. Endereços (endpoints) são como "gavetas" no servidor; a gaveta <strong>'${resource}'</strong> não foi encontrada.`;
updateResponseUI(status, statusText, headers, responseBody, analysis);
return;
}
switch (method) {
case 'GET':
if (id) {
const item = db[resource].find(u => u.id === id);
if (item) {
status = 200; statusText = 'OK'; responseBody = item;
analysis = `<strong>Status 200 OK:</strong> Sucesso! O servidor encontrou e retornou o recurso específico que você pediu (id ${id}).`;
} else {
status = 404; statusText = 'Not Found'; responseBody = { erro: `Recurso com id ${id} não encontrado em '${resource}'.` };
analysis = `<strong>Status 404 Not Found:</strong> O servidor entendeu o pedido, mas não encontrou o item específico. É como pedir um produto que não existe no estoque.`;
}
} else {
status = 200; statusText = 'OK'; responseBody = db[resource];
analysis = `<strong>Status 200 OK:</strong> Sucesso! O servidor retornou a lista completa de todos os '${resource}'.`;
}
break;
case 'POST':
try {
const newItem = JSON.parse(body);
if (!newItem.nome) throw new Error();
newItem.id = resource === 'usuarios' ? nextUserId++ : nextProductId++;
db[resource].push(newItem);
status = 201; statusText = 'Created'; responseBody = newItem;
analysis = `<strong>Status 201 Created:</strong> Sucesso ao criar! O servidor recebeu os dados do 'Body', criou um novo recurso e o retornou com um 'id' novo.`;
} catch(e) {
status = 400; statusText = 'Bad Request'; responseBody = { erro: 'Corpo (JSON) inválido ou faltando campos obrigatórios.' };
analysis = `<strong>Status 400 Bad Request:</strong> O servidor não entendeu o que você mandou no 'Body'. Verifique se o JSON está bem formatado.`;
}
break;
case 'PUT':
if (!id) { status = 400; statusText = 'Bad Request'; responseBody = { erro: 'ID é necessário na URL para atualização.' }; analysis = `<strong>Status 400 Bad Request:</strong> Para o método PUT, você deve especificar *qual* recurso quer atualizar. Faltou o ID na URL.`; break; }
try {
const updatedData = JSON.parse(body);
const itemIndex = db[resource].findIndex(u => u.id === id);
if (itemIndex > -1) {
db[resource][itemIndex] = { ...db[resource][itemIndex], ...updatedData };
status = 200; statusText = 'OK'; responseBody = db[resource][itemIndex];
analysis = `<strong>Status 200 OK:</strong> Sucesso ao atualizar! O recurso com id ${id} foi atualizado com os dados do 'Body'.`;
} else {
status = 404; statusText = 'Not Found'; responseBody = { erro: `Recurso com id ${id} não encontrado para atualizar.` };
analysis = `<strong>Status 404 Not Found:</strong> Não foi possível atualizar, pois o recurso com id ${id} não foi encontrado.`;
}
} catch(e) {
status = 400; statusText = 'Bad Request'; responseBody = { erro: 'Corpo da requisição (JSON) inválido.' };
analysis = `<strong>Status 400 Bad Request:</strong> O JSON enviado no 'Body' para atualização está mal formatado.`;
}
break;
case 'DELETE':
if (!id) { status = 400; statusText = 'Bad Request'; responseBody = { erro: 'ID é necessário na URL para deleção.' }; analysis = `<strong>Status 400 Bad Request:</strong> Para o método DELETE, é essencial especificar *qual* recurso você quer apagar.`; break; }
const itemIndexDel = db[resource].findIndex(u => u.id === id);
if (itemIndexDel > -1) {
db[resource].splice(itemIndexDel, 1);
status = 200; statusText = 'OK'; responseBody = { mensagem: `Recurso com id ${id} deletado com sucesso.` };
analysis = `<strong>Status 200 OK:</strong> Sucesso! O recurso com id ${id} foi removido permanentemente.`;
} else {
status = 404; statusText = 'Not Found'; responseBody = { erro: `Recurso com id ${id} não encontrado para deletar.` };
analysis = `<strong>Status 404 Not Found:</strong> Não foi possível deletar, pois o recurso não foi encontrado.`;
}
break;
}
updateResponseUI(status, statusText, headers, responseBody, analysis);
}, 1000);
}
methodSelect.addEventListener('change', () => { toggleBodyInput(); updateBodyPlaceholder(); });
urlSelect.addEventListener('change', updateBodyPlaceholder);
sendBtn.addEventListener('click', handleRequest);
toggleBodyInput();
updateBodyPlaceholder();
handleRequest();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment