28 KiB
Documentação Técnica das APIs - OllaHubBackend
Visão Geral
O OllaHubBackend é uma API REST desenvolvida em Rust (Actix Web) que fornece gerenciamento de modelos Ollama, operações criptográficas, gerenciamento de usuários e comunicação em tempo real via WebSocket.
Base URL
- Desenvolvimento:
http://127.0.0.1:8080 - Produção: [A definir]
Versões da API
- V1 (Legado): Endpoints implementados diretamente no
main.rs - V2 (Modular): Endpoints organizados em módulos (
src/api/mod.rs) - Recomendado - Usuários V1: CRUD de usuários em
/api/v1/users
Swagger UI
Documentação interativa disponível em: http://127.0.0.1:8080/docs
Autenticação
A API utiliza JWT (JSON Web Tokens) para autenticação. Endpoints protegidos requerem o header de autorização.
Como Autenticar
Authorization: Bearer <seu_token_jwt>
Endpoints Protegidos
Os seguintes caminhos requerem autenticação JWT:
/api/v1/*(todos os endpoints de usuários)/v2/api/crypto/*(todas as operações de criptografia)/v2/api/models/*(operações de modelos)
Endpoints Públicos
GET /healthGET /v2/healthGET /v2/api/ollama/checkPOST /v2/api/ollama/installWS /v2/ws(WebSocket)
Configuração JWT
A chave secreta JWT é configurada via variável de ambiente:
- Variável:
JWT_SECRET - Padrão (dev):
changeme-dev-secret
Endpoints
Sistema / Health
GET /health
Verifica o status básico da API.
Autenticação: Não requerida
Resposta:
"ok"
Exemplo:
curl http://127.0.0.1:8080/health
GET /v2/health
Verifica o status da API V2.
Autenticação: Não requerida
Resposta:
{
"status": "ok"
}
Exemplo:
curl http://127.0.0.1:8080/v2/health
Ollama - Instalação e Verificação
GET /v2/api/ollama/check
Verifica se o Ollama está instalado e acessível no sistema.
Autenticação: Não requerida
Resposta:
{
"installed": true,
"in_path": true,
"version": "0.1.15",
"service_running": true,
"api_status": "reachable",
"details": {
"native_version": "ollama version is 0.1.15",
"api_/api/version": "{\"version\":\"0.1.15\"}",
"api_/api/tags": "{\"models\":[...]}",
"security_antivirus_active": "false",
"security_antivirus_instructions": "..."
},
"issues": []
}
Campos da Resposta:
installed(boolean): Se o Ollama está instaladoin_path(boolean): Se o binário está no PATHversion(string|null): Versão do Ollamaservice_running(boolean): Se o serviço está rodandoapi_status(string):"reachable","unreachable"ou"degraded"details(object): Detalhes técnicos da instalaçãoissues(array): Lista de problemas encontrados
Exemplo:
curl http://127.0.0.1:8080/v2/api/ollama/check
POST /v2/api/ollama/install
Inicia o processo de instalação automática do Ollama (se não estiver instalado) e garante que o serviço esteja rodando. O progresso é enviado via WebSocket.
Autenticação: Não requerida
Request Body (opcional):
{
"method": "auto",
"platform": "auto"
}
Resposta:
{
"status": "started",
"operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
Campos da Resposta:
status(string): Status da operação ("started")operation_id(string): UUID da operação para rastreamento via WebSocket
Eventos WebSocket:
Log: Mensagens de log durante a instalaçãoProgress: Progresso da instalaçãoDone: Instalação concluída com sucessoError: Erro durante a instalação
Exemplo:
curl -X POST http://127.0.0.1:8080/v2/api/ollama/install \
-H "Content-Type: application/json" \
-d '{"method": "auto", "platform": "auto"}'
Notas:
- A instalação é específica por plataforma (Windows, Linux, macOS)
- O progresso é enviado via WebSocket (
WS /v2/ws) - Em caso de falha, eventos
Errorsão enviados via WebSocket - Os endpoints V1 (
GET /ollama/install-checkePOST /ollama/install) foram removidos
Modelos (V2)
GET /v2/api/models
Lista todos os modelos disponíveis do arquivo modelList.json.
Autenticação: Requerida (JWT)
Resposta:
[
{
"name": "llama2",
"description": "Modelo LLaMA 2"
},
{
"name": "mistral",
"description": "Modelo Mistral"
}
]
Códigos de Status:
200 OK: Sucesso401 Unauthorized: Token JWT inválido ou ausente500 Internal Server Error: Erro ao ler arquivo de modelos
Exemplo:
curl -H "Authorization: Bearer <token>" \
http://127.0.0.1:8080/v2/api/models
JavaScript/TypeScript:
const response = await fetch('http://127.0.0.1:8080/v2/api/models', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const models = await response.json();
POST /v2/api/models/install
Inicia a instalação (download) de um modelo do Ollama. O progresso é enviado via WebSocket.
Autenticação: Requerida (JWT)
Request Body:
{
"name": "llama2:7b"
}
Resposta:
{
"status": "started",
"model": "llama2:7b"
}
Códigos de Status:
202 Accepted: Instalação iniciada400 Bad Request: Nome do modelo inválido401 Unauthorized: Token JWT inválido ou ausente500 Internal Server Error: Erro ao iniciar instalação
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"llama2:7b"}' \
http://127.0.0.1:8080/v2/api/models/install
JavaScript/TypeScript:
const response = await fetch('http://127.0.0.1:8080/v2/api/models/install', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'llama2:7b' })
});
const result = await response.json();
Notas:
- O progresso da instalação é enviado via WebSocket (
/v2/ws) - Conecte-se ao WebSocket antes de iniciar a instalação para receber eventos
- O formato do nome pode incluir tag:
"modelo:tag"(ex:"llama2:7b")
Criptografia (V2)
Todas as operações de criptografia usam AES-256-GCM com chave de 32 bytes.
POST /v2/api/crypto/set-key
Define a chave de criptografia (deve ser chamado antes de usar encrypt/decrypt).
Autenticação: Requerida (JWT)
Request Body:
{
"hex_key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
Resposta:
{
"ok": true
}
Códigos de Status:
200 OK: Chave definida com sucesso400 Bad Request: Chave inválida (deve ter 64 caracteres hex = 32 bytes)401 Unauthorized: Token JWT inválido ou ausente409 Conflict: Chave já foi definida anteriormente
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"hex_key":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}' \
http://127.0.0.1:8080/v2/api/crypto/set-key
Notas:
- A chave é persistida no disco automaticamente
- Use a mesma chave no frontend para operações de criptografia
- A chave deve ter exatamente 64 caracteres hexadecimais (32 bytes)
POST /v2/api/crypto/rotate-key
Gera uma nova chave de criptografia aleatória e retorna em hexadecimal.
Autenticação: Requerida (JWT)
Resposta:
{
"key": "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456"
}
Códigos de Status:
200 OK: Chave rotacionada com sucesso401 Unauthorized: Token JWT inválido ou ausente500 Internal Server Error: Erro ao gerar/salvar chave
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
http://127.0.0.1:8080/v2/api/crypto/rotate-key
Notas:
- A nova chave substitui a anterior
- Salve a chave retornada para uso no frontend
- A chave é automaticamente persistida no disco
POST /v2/api/crypto/encrypt
Criptografa dados usando AES-256-GCM.
Autenticação: Requerida (JWT)
Request Body:
{
"data": "dados sensíveis para criptografar"
}
Resposta:
{
"ciphertext": "base64_encoded_ciphertext_with_nonce"
}
Códigos de Status:
200 OK: Criptografia bem-sucedida400 Bad Request: Chave não definida ou dados inválidos401 Unauthorized: Token JWT inválido ou ausente
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"data":"minha senha secreta"}' \
http://127.0.0.1:8080/v2/api/crypto/encrypt
Notas:
- O nonce (12 bytes) é incluído automaticamente no início do ciphertext
- O resultado é retornado em Base64
- O formato do ciphertext:
[nonce 12 bytes][ciphertext](tudo em Base64)
POST /v2/api/crypto/decrypt
Descriptografa dados usando AES-256-GCM.
Autenticação: Requerida (JWT)
Request Body:
{
"data": "base64_encoded_ciphertext_with_nonce"
}
Resposta:
{
"plaintext": "dados descriptografados"
}
Códigos de Status:
200 OK: Descriptografia bem-sucedida400 Bad Request: Chave não definida, Base64 inválido ou tag de autenticação inválida401 Unauthorized: Token JWT inválido ou ausente
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"data":"ciphertext_base64_aqui"}' \
http://127.0.0.1:8080/v2/api/crypto/decrypt
Notas:
- O nonce é extraído automaticamente dos primeiros 12 bytes
- O
datadeve ser o mesmociphertextretornado porencrypt - A tag de autenticação GCM é verificada automaticamente
Usuários (V1)
GET /api/v1/users
Lista todos os usuários cadastrados.
Autenticação: Requerida (JWT)
Resposta:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "[email protected]"
},
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"name": "Maria Santos",
"email": "[email protected]"
}
]
Códigos de Status:
200 OK: Sucesso401 Unauthorized: Token JWT inválido ou ausente
Exemplo:
curl -H "Authorization: Bearer <token>" \
http://127.0.0.1:8080/api/v1/users
GET /api/v1/users/{id}
Obtém um usuário específico por ID.
Autenticação: Requerida (JWT)
Parâmetros de Path:
id(string): UUID do usuário
Resposta:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "[email protected]"
}
Códigos de Status:
200 OK: Usuário encontrado401 Unauthorized: Token JWT inválido ou ausente404 Not Found: Usuário não encontrado
Exemplo:
curl -H "Authorization: Bearer <token>" \
http://127.0.0.1:8080/api/v1/users/550e8400-e29b-41d4-a716-446655440000
POST /api/v1/users
Cria um novo usuário.
Autenticação: Requerida (JWT)
Request Body:
{
"name": "João Silva",
"email": "[email protected]"
}
Validações:
name: Mínimo 2 caracteresemail: Formato de email válido
Resposta:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva",
"email": "[email protected]"
}
Códigos de Status:
201 Created: Usuário criado com sucesso400 Bad Request: Erro de validação401 Unauthorized: Token JWT inválido ou ausente
Exemplo:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"João Silva","email":"[email protected]"}' \
http://127.0.0.1:8080/api/v1/users
PUT /api/v1/users/{id}
Atualiza um usuário existente.
Autenticação: Requerida (JWT)
Parâmetros de Path:
id(string): UUID do usuário
Request Body:
{
"name": "João Silva Atualizado",
"email": "[email protected]"
}
Validações:
name: Mínimo 2 caracteres (opcional)email: Formato de email válido (opcional)
Resposta:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "João Silva Atualizado",
"email": "[email protected]"
}
Códigos de Status:
200 OK: Usuário atualizado400 Bad Request: Erro de validação401 Unauthorized: Token JWT inválido ou ausente404 Not Found: Usuário não encontrado
Exemplo:
curl -X PUT \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"João Silva Atualizado","email":"[email protected]"}' \
http://127.0.0.1:8080/api/v1/users/550e8400-e29b-41d4-a716-446655440000
DELETE /api/v1/users/{id}
Remove um usuário.
Autenticação: Requerida (JWT)
Parâmetros de Path:
id(string): UUID do usuário
Resposta: Sem corpo (204 No Content)
Códigos de Status:
204 No Content: Usuário removido401 Unauthorized: Token JWT inválido ou ausente404 Not Found: Usuário não encontrado
Exemplo:
curl -X DELETE \
-H "Authorization: Bearer <token>" \
http://127.0.0.1:8080/api/v1/users/550e8400-e29b-41d4-a716-446655440000
WebSocket (V2)
WS /v2/ws
Endpoint WebSocket para receber eventos em tempo real, especialmente durante a instalação de modelos.
Autenticação: Não requerida (mas pode ser implementada)
Conexão:
ws://127.0.0.1:8080/v2/ws
Tipos de Eventos:
- Log: Mensagens de log durante operações
{
"kind": "Log",
"message": "Downloading model llama2:7b..."
}
- Progress: Progresso de operações (ex: download de modelo)
{
"kind": "Progress",
"message": "{\"status\":\"downloading\",\"completed\":50,\"total\":100}"
}
- Done: Operação concluída
{
"kind": "Done",
"message": "Download do modelo 'llama2:7b' concluído"
}
- Error: Erro durante operação
{
"kind": "Error",
"message": "Falha ao conectar com API do Ollama"
}
Exemplo JavaScript:
const ws = new WebSocket('ws://127.0.0.1:8080/v2/ws');
ws.onopen = () => {
console.log('WebSocket conectado');
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Evento recebido:', data);
switch(data.kind) {
case 'Log':
console.log('Log:', data.message);
break;
case 'Progress':
console.log('Progresso:', data.message);
break;
case 'Done':
console.log('Concluído:', data.message);
break;
case 'Error':
console.error('Erro:', data.message);
break;
}
};
ws.onerror = (error) => {
console.error('Erro WebSocket:', error);
};
ws.onclose = () => {
console.log('WebSocket desconectado');
};
Exemplo TypeScript:
enum WsEventKind {
Log = 'Log',
Progress = 'Progress',
Done = 'Done',
Error = 'Error'
}
interface WsEvent {
kind: WsEventKind;
message: string;
}
const ws = new WebSocket('ws://127.0.0.1:8080/v2/ws');
ws.onmessage = (event: MessageEvent) => {
const data: WsEvent = JSON.parse(event.data);
// Processar evento
};
Fluxo de Instalação de Modelo:
- Conecte-se ao WebSocket
- Chame
POST /v2/api/models/installcom o nome do modelo - Receba eventos via WebSocket:
Log: Mensagens de progressoProgress: Atualizações de progresso (se disponível)Done: Instalação concluídaError: Erro durante instalação
Notas:
- O WebSocket mantém a conexão aberta para receber múltiplos eventos
WebSocket Chat (/v2/ws/chat)
Endpoint WebSocket dedicado para chat com modelos Ollama, oferecendo streaming em tempo real das respostas.
Conectar
const ws = new WebSocket('ws://127.0.0.1:8080/v2/ws/chat');
ws.onopen = () => {
console.log('Chat WebSocket conectado');
// Enviar mensagem de chat
const chatRequest = {
model: "llama2",
messages: [
{ role: "user", content: "Olá, como você está?" }
],
stream: true,
options: {
temperature: 0.7,
top_p: 0.9
}
};
ws.send(JSON.stringify(chatRequest));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.done) {
console.log('Chat finalizado');
return;
}
if (response.message) {
// Acumular conteúdo da mensagem
console.log('Chunk recebido:', response.message.content);
}
if (response.error) {
console.error('Erro no chat:', response.error);
}
};
ws.onerror = (error) => {
console.error('Erro WebSocket chat:', error);
};
ws.onclose = () => {
console.log('Chat WebSocket desconectado');
};
Formato da Requisição
{
"model": "llama2",
"messages": [
{ "role": "user", "content": "Sua mensagem aqui" },
{ "role": "assistant", "content": "Resposta anterior" }
],
"stream": true,
"options": {
"temperature": 0.7,
"top_p": 0.9,
"top_k": 40
}
}
Campos:
model(string, obrigatório): Nome do modelo a ser usadomessages(array, obrigatório): Array de mensagens no formato{ role: "user"|"assistant", content: string }stream(boolean, opcional): Sempretruepara streaming (padrão:true)options(object, opcional): Opções do modelo (temperature, top_p, top_k, etc.)
Formato da Resposta (Streaming)
Cada chunk recebido é um objeto JSON:
{
"model": "llama2",
"created_at": "2024-01-01T12:00:00Z",
"message": {
"role": "assistant",
"content": "Olá! Estou bem, obrigado por perguntar."
},
"done": false
}
Último chunk (quando done: true):
{
"model": "llama2",
"created_at": "2024-01-01T12:00:05Z",
"message": null,
"done": true,
"total_duration": 5000000000,
"load_duration": 100000000,
"prompt_eval_count": 10,
"prompt_eval_duration": 200000000,
"eval_count": 50,
"eval_duration": 4700000000
}
Características
- Streaming em tempo real: Respostas são enviadas chunk por chunk conforme geradas
- Baixa latência: WebSocket mantém conexão persistente
- Heartbeat: Ping/pong automático a cada 5 segundos
- Timeout: Desconexão automática após 30 segundos de inatividade
- Múltiplas conversas: Uma conexão pode enviar múltiplas requisições de chat
Exemplo Completo: Conversa com Histórico
const ws = new WebSocket('ws://127.0.0.1:8080/v2/ws/chat');
let conversationHistory = [];
ws.onopen = () => {
sendMessage("Olá!");
};
function sendMessage(userMessage) {
// Adicionar mensagem do usuário ao histórico
conversationHistory.push({ role: "user", content: userMessage });
const request = {
model: "llama2",
messages: conversationHistory,
stream: true
};
ws.send(JSON.stringify(request));
}
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.done) {
// Adicionar resposta completa ao histórico
if (response.message) {
conversationHistory.push(response.message);
}
console.log('Conversa atualizada:', conversationHistory);
return;
}
// Acumular chunks da resposta
if (response.message && response.message.content) {
process.stdout.write(response.message.content);
}
};
// Enviar próxima mensagem após resposta completa
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.done) {
if (response.message) {
conversationHistory.push(response.message);
}
// Próxima mensagem do usuário
sendMessage("Conte-me uma piada");
} else if (response.message) {
process.stdout.write(response.message.content);
}
};
Tratamento de Erros
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
if (response.error) {
console.error('Erro do Ollama:', response.error);
// Erro pode ocorrer em qualquer chunk
}
if (response.done && response.error) {
// Erro final - conexão pode ser fechada
ws.close();
}
};
Notas Importantes
- O endpoint requer autenticação JWT (mesmo token usado em outras APIs)
- O WebSocket mantém a conexão aberta para múltiplas requisições
- Cada requisição deve incluir o histórico completo da conversa
- Respostas são enviadas em formato JSON lines (uma linha por chunk)
- Use
done: truepara saber quando a resposta está completa - Eventos são broadcast para todos os clientes conectados
- Ping/Pong são gerenciados automaticamente
Modelos de Dados
User
interface User {
id: string; // UUID
name: string; // Mínimo 2 caracteres
email: string; // Email válido
}
CreateUserRequest
interface CreateUserRequest {
name: string; // Mínimo 2 caracteres
email: string; // Email válido
}
UpdateUserRequest
interface UpdateUserRequest {
name?: string; // Mínimo 2 caracteres (opcional)
email?: string; // Email válido (opcional)
}
ModelInfo
interface ModelInfo {
name: string;
description?: string;
}
InstallReq
interface InstallReq {
name: string; // Nome do modelo (ex: "llama2:7b")
}
SetKeyReq
interface SetKeyReq {
hex_key: string; // 64 caracteres hex (32 bytes)
}
CryptReq
interface CryptReq {
data: string; // Dados para criptografar/descriptografar
}
ApiErrorBody
interface ApiErrorBody {
error: string; // Mensagem de erro
}
WsEvent
enum WsEventKind {
Log = 'Log',
Progress = 'Progress',
Done = 'Done',
Error = 'Error'
}
interface WsEvent {
kind: WsEventKind;
message: string;
}
Tratamento de Erros
Códigos de Status HTTP
200 OK: Requisição bem-sucedida201 Created: Recurso criado com sucesso202 Accepted: Requisição aceita para processamento assíncrono204 No Content: Sucesso sem conteúdo de retorno400 Bad Request: Erro na requisição (validação, formato)401 Unauthorized: Token JWT ausente ou inválido404 Not Found: Recurso não encontrado409 Conflict: Conflito (ex: chave já definida)500 Internal Server Error: Erro interno do servidor
Formato de Erro
Todos os erros retornam o seguinte formato:
{
"error": "Mensagem de erro descritiva"
}
Exemplos de Erros
400 Bad Request:
{
"error": "validação: email: deve ser um email válido"
}
401 Unauthorized:
{
"error": "Token JWT inválido ou ausente"
}
404 Not Found:
{
"error": "Usuário não encontrado"
}
500 Internal Server Error:
{
"error": "Falha ao ler arquivo de modelos: No such file or directory"
}
Variáveis de Ambiente
OLLAMA_BASE_URL
- Descrição: URL base da API do Ollama
- Padrão:
http://localhost:11434 - Uso: Usado para comunicação com o Ollama
MODEL_LIST_PATH
- Descrição: Caminho para o arquivo JSON com lista de modelos
- Padrão:
modelList.json - Uso: Arquivo lido para listar modelos disponíveis
JWT_SECRET
- Descrição: Chave secreta para assinatura de tokens JWT
- Padrão:
changeme-dev-secret - Uso: Validação de tokens JWT
- Importante:
- Deve ser o mesmo valor usado no frontend para gerar tokens
- Altere em produção!
- Pode ser configurado via variável de ambiente ou arquivo
.env
Configuração via .env (recomendado):
JWT_SECRET=5741f9da3be6007674a5e10edab7b124
Configuração via variável de ambiente:
# Windows (PowerShell)
$env:JWT_SECRET="5741f9da3be6007674a5e10edab7b124"
# Linux/Mac
export JWT_SECRET="5741f9da3be6007674a5e10edab7b124"
SKIP_ANTIVIRUS_WARNINGS
- Descrição: Suprime avisos de verificação de antivírus durante inicialização
- Padrão:
false - Valores:
trueoufalse - Uso: Define como
truepara desabilitar avisos informativos sobre antivírus/segurança - Exemplo:
SKIP_ANTIVIRUS_WARNINGS=true cargo run
Exemplos de Fluxos Completos
Fluxo 1: Instalar um Modelo com Acompanhamento via WebSocket
// 1. Conectar ao WebSocket
const ws = new WebSocket('ws://127.0.0.1:8080/v2/ws');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.kind === 'Done') {
console.log('Modelo instalado!');
}
};
// 2. Aguardar conexão
ws.onopen = async () => {
// 3. Iniciar instalação
const response = await fetch('http://127.0.0.1:8080/v2/api/models/install', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'llama2:7b' })
});
const result = await response.json();
console.log('Instalação iniciada:', result);
};
Fluxo 2: Configurar Criptografia e Criptografar Dados
// 1. Definir chave (ou rotacionar)
const rotateResponse = await fetch('http://127.0.0.1:8080/v2/api/crypto/rotate-key', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
}
});
const { key } = await rotateResponse.json();
console.log('Nova chave:', key);
// 2. Criptografar dados
const encryptResponse = await fetch('http://127.0.0.1:8080/v2/api/crypto/encrypt', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: 'dados sensíveis' })
});
const { ciphertext } = await encryptResponse.json();
console.log('Dados criptografados:', ciphertext);
// 3. Descriptografar
const decryptResponse = await fetch('http://127.0.0.1:8080/v2/api/crypto/decrypt', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ data: ciphertext })
});
const { plaintext } = await decryptResponse.json();
console.log('Dados descriptografados:', plaintext);
Fluxo 3: CRUD Completo de Usuários
const baseUrl = 'http://127.0.0.1:8080/api/v1/users';
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
// 1. Criar usuário
const createResponse = await fetch(baseUrl, {
method: 'POST',
headers,
body: JSON.stringify({
name: 'João Silva',
email: '[email protected]'
})
});
const newUser = await createResponse.json();
console.log('Usuário criado:', newUser);
// 2. Listar usuários
const listResponse = await fetch(baseUrl, { headers });
const users = await listResponse.json();
console.log('Usuários:', users);
// 3. Obter usuário específico
const getUserResponse = await fetch(`${baseUrl}/${newUser.id}`, { headers });
const user = await getUserResponse.json();
console.log('Usuário:', user);
// 4. Atualizar usuário
const updateResponse = await fetch(`${baseUrl}/${newUser.id}`, {
method: 'PUT',
headers,
body: JSON.stringify({
name: 'João Silva Atualizado',
email: '[email protected]'
})
});
const updatedUser = await updateResponse.json();
console.log('Usuário atualizado:', updatedUser);
// 5. Deletar usuário
await fetch(`${baseUrl}/${newUser.id}`, {
method: 'DELETE',
headers
});
console.log('Usuário deletado');
Notas Importantes
Segurança
- JWT Secret: Sempre altere o
JWT_SECRETem produção - HTTPS: Use HTTPS em produção para proteger tokens e dados
- Chave de Criptografia: Mantenha a chave de criptografia segura e nunca a exponha
- Validação: Todos os inputs são validados no backend
Performance
- WebSocket: Use WebSocket para operações longas (instalação de modelos)
- Assíncrono: Instalação de modelos é assíncrona (202 Accepted)
- Cache: Considere cachear lista de modelos no frontend
Compatibilidade
- V1 vs V2: Prefira endpoints V2 quando disponíveis
- Swagger: Use
/docspara documentação interativa - Versões: Endpoints V1 podem ser descontinuados no futuro
Limitações
- Armazenamento de Usuários: Atualmente em memória (perdido ao reiniciar)
- Chave de Criptografia: Uma chave por instância do servidor
- WebSocket: Broadcast para todos os clientes (não filtrado por operação)
Suporte e Recursos
- Swagger UI:
http://127.0.0.1:8080/docs - Health Check:
http://127.0.0.1:8080/health - Código Fonte: Ver repositório do projeto
Última Atualização: 2024