Radar DOU
Voltar para API e Desenvolvedores
API e Desenvolvedores

Exemplos em JavaScript

5 min de leitura

Este guia apresenta exemplos praticos de integracao com a API do Radar DOU utilizando JavaScript, tanto para Node.js quanto para aplicacoes frontend no navegador.

Instalacao do SDK

A maneira mais facil de integrar com a API e utilizando nosso SDK oficial:

# npm
npm install radardou

# yarn
yarn add radardou

# pnpm
pnpm add radardou

Configuracao Inicial

Usando o SDK

import { RadarDOU } from 'radardou';

// Inicializar o cliente
const radar = new RadarDOU({
  apiKey: process.env.RADAR_DOU_API_KEY,
  // Opcoes adicionais
  timeout: 30000,        // Timeout em ms (default: 30000)
  retries: 3,            // Tentativas em caso de erro (default: 3)
  baseUrl: 'https://radardou.com.br/api/v1'  // URL base (opcional)
});

Usando Fetch Nativo

const API_KEY = process.env.RADAR_DOU_API_KEY;
const BASE_URL = 'https://radardou.com.br/api/v1';

async function apiRequest(endpoint, params = {}) {
  const url = new URL(`${BASE_URL}${endpoint}`);
  Object.keys(params).forEach(key =>
    url.searchParams.append(key, params[key])
  );

  const response = await fetch(url, {
    method: 'GET',
    headers: {
      'X-API-Key': API_KEY,
      'Content-Type': 'application/json'
    }
  });

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  return response.json();
}

Busca de Publicacoes

Busca Simples com SDK

import { RadarDOU } from 'radardou';

const radar = new RadarDOU({ apiKey: process.env.RADAR_DOU_API_KEY });

async function buscarPublicacoes() {
  try {
    const resultado = await radar.buscar({
      termo: 'licitacao',
      limite: 10
    });

    console.log(`Total encontrado: ${resultado.total}`);

    resultado.resultados.forEach(pub => {
      console.log(`- ${pub.titulo}`);
      console.log(`  Data: ${pub.data_publicacao}`);
      console.log(`  Orgao: ${pub.orgao}`);
    });

    return resultado;
  } catch (error) {
    console.error('Erro na busca:', error.message);
  }
}

buscarPublicacoes();

Busca com Filtros Avancados

async function buscarComFiltros() {
  const resultado = await radar.buscar({
    termo: 'contrato administrativo',
    data_inicio: '2024-01-01',
    data_fim: '2024-06-30',
    secao: '3',
    orgao: 'Ministerio da Saude',
    tipo_ato: 'Extrato de Contrato',
    limite: 50,
    pagina: 1
  });

  return resultado;
}

Paginacao de Resultados

async function buscarTodosResultados(termo) {
  const todosResultados = [];
  let pagina = 1;
  let temMais = true;

  while (temMais) {
    const resultado = await radar.buscar({
      termo,
      pagina,
      limite: 100  // Maximo por requisicao
    });

    todosResultados.push(...resultado.resultados);

    console.log(`Pagina ${pagina}/${resultado.total_paginas} - ${todosResultados.length}/${resultado.total}`);

    if (pagina >= resultado.total_paginas) {
      temMais = false;
    } else {
      pagina++;
      // Respeitar rate limit - aguardar entre requisicoes
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }

  return todosResultados;
}

// Uso
const publicacoes = await buscarTodosResultados('pregao eletronico');
console.log(`Total coletado: ${publicacoes.length}`);

Obtendo Detalhes de uma Publicacao

async function obterDetalhes(publicacaoId) {
  try {
    const publicacao = await radar.publicacao(publicacaoId);

    console.log('=== DETALHES DA PUBLICACAO ===');
    console.log(`Titulo: ${publicacao.titulo}`);
    console.log(`Data: ${publicacao.data_publicacao}`);
    console.log(`Secao: ${publicacao.secao}`);
    console.log(`Pagina: ${publicacao.pagina}`);
    console.log(`Orgao: ${publicacao.orgao}`);
    console.log(`Tipo: ${publicacao.tipo_ato}`);
    console.log('');
    console.log('Conteudo:');
    console.log(publicacao.conteudo_completo);

    if (publicacao.publicacoes_relacionadas?.length > 0) {
      console.log('');
      console.log('Publicacoes relacionadas:', publicacao.publicacoes_relacionadas);
    }

    return publicacao;
  } catch (error) {
    if (error.status === 404) {
      console.error('Publicacao nao encontrada');
    } else {
      console.error('Erro:', error.message);
    }
  }
}

// Uso
await obterDetalhes('pub_abc123');

Listando Secoes e Edicoes

// Listar todas as secoes disponiveis
async function listarSecoes() {
  const secoes = await radar.secoes();

  secoes.forEach(secao => {
    console.log(`${secao.codigo}: ${secao.nome}`);
    console.log(`   ${secao.descricao}`);
  });

  return secoes;
}

// Listar edicoes de um mes especifico
async function listarEdicoes(mes) {
  const edicoes = await radar.edicoes({ mes });

  edicoes.forEach(edicao => {
    console.log(`Edicao ${edicao.numero} - ${edicao.data}`);
    console.log(`   Tipo: ${edicao.tipo}`);
    console.log(`   Secoes: ${edicao.secoes.join(', ')}`);
    console.log(`   Total publicacoes: ${edicao.total_publicacoes}`);
  });

  return edicoes;
}

// Uso
await listarSecoes();
await listarEdicoes('2024-06');

Exemplo com TypeScript

import { RadarDOU, Publicacao, BuscaParams, BuscaResultado } from 'radardou';

interface PublicacaoProcessada {
  id: string;
  titulo: string;
  data: Date;
  orgao: string;
  valor?: number;
}

async function processarPublicacoes(termo: string): Promise<PublicacaoProcessada[]> {
  const radar = new RadarDOU({ apiKey: process.env.RADAR_DOU_API_KEY! });

  const params: BuscaParams = {
    termo,
    secao: '3',
    limite: 50
  };

  const resultado: BuscaResultado = await radar.buscar(params);

  return resultado.resultados.map((pub: Publicacao): PublicacaoProcessada => ({
    id: pub.id,
    titulo: pub.titulo,
    data: new Date(pub.data_publicacao),
    orgao: pub.orgao,
    valor: extrairValor(pub.resumo)
  }));
}

function extrairValor(texto: string): number | undefined {
  const match = texto.match(/R\$\s*([\d.,]+)/);
  if (match) {
    return parseFloat(match[1].replace(/\./g, '').replace(',', '.'));
  }
  return undefined;
}

Exemplo com React/Next.js

// app/api/buscar/route.ts (Next.js App Router)
import { NextRequest, NextResponse } from 'next/server';
import { RadarDOU } from 'radardou';

const radar = new RadarDOU({ apiKey: process.env.RADAR_DOU_API_KEY! });

export async function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams;
  const termo = searchParams.get('termo');

  if (!termo) {
    return NextResponse.json(
      { erro: 'Parametro termo e obrigatorio' },
      { status: 400 }
    );
  }

  try {
    const resultado = await radar.buscar({
      termo,
      limite: parseInt(searchParams.get('limite') || '20'),
      pagina: parseInt(searchParams.get('pagina') || '1')
    });

    return NextResponse.json(resultado);
  } catch (error) {
    return NextResponse.json(
      { erro: 'Erro ao buscar publicacoes' },
      { status: 500 }
    );
  }
}

// components/BuscaPublicacoes.tsx
'use client';
import { useState } from 'react';

export function BuscaPublicacoes() {
  const [termo, setTermo] = useState('');
  const [resultados, setResultados] = useState([]);
  const [loading, setLoading] = useState(false);

  async function handleBuscar(e) {
    e.preventDefault();
    setLoading(true);

    try {
      const res = await fetch(`/api/buscar?termo=${encodeURIComponent(termo)}`);
      const data = await res.json();
      setResultados(data.resultados || []);
    } catch (error) {
      console.error('Erro:', error);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <form onSubmit={handleBuscar}>
        <input
          type="text"
          value={termo}
          onChange={(e) => setTermo(e.target.value)}
          placeholder="Buscar no DOU..."
        />
        <button type="submit" disabled={loading}>
          {loading ? 'Buscando...' : 'Buscar'}
        </button>
      </form>

      <ul>
        {resultados.map((pub) => (
          <li key={pub.id}>
            <strong>{pub.titulo}</strong>
            <span>{pub.data_publicacao}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

Tratamento de Erros

import { RadarDOU, RadarDOUError, RateLimitError, AuthenticationError } from 'radardou';

async function buscarComTratamentoErros(termo) {
  const radar = new RadarDOU({ apiKey: process.env.RADAR_DOU_API_KEY });

  try {
    const resultado = await radar.buscar({ termo });
    return resultado;

  } catch (error) {
    if (error instanceof AuthenticationError) {
      console.error('Erro de autenticacao - verifique sua API Key');
      // Redirecionar para pagina de configuracao ou notificar admin

    } else if (error instanceof RateLimitError) {
      console.error('Limite de requisicoes excedido');
      console.log(`Tente novamente em: ${error.retryAfter} segundos`);

      // Aguardar e tentar novamente
      await new Promise(resolve =>
        setTimeout(resolve, error.retryAfter * 1000)
      );
      return buscarComTratamentoErros(termo);

    } else if (error instanceof RadarDOUError) {
      console.error(`Erro da API: ${error.message}`);
      console.error(`Codigo: ${error.code}`);
      console.error(`Request ID: ${error.requestId}`);

    } else {
      console.error('Erro desconhecido:', error);
    }

    throw error;
  }
}

Boas Praticas

Recomendacoes

  • Use variaveis de ambiente para a API Key
  • Implemente cache para reducir requisicoes repetidas
  • Respeite os rate limits com delays entre requisicoes em lote
  • Use async/await para codigo mais legivel
  • Implemente retry com backoff exponencial
  • Valide dados de entrada antes de enviar a API

Implementando Cache

import { RadarDOU } from 'radardou';

// Cache simples em memoria
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutos

async function buscarComCache(termo, params = {}) {
  const cacheKey = JSON.stringify({ termo, ...params });

  // Verificar cache
  const cached = cache.get(cacheKey);
  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    console.log('Retornando do cache');
    return cached.data;
  }

  // Buscar da API
  const radar = new RadarDOU({ apiKey: process.env.RADAR_DOU_API_KEY });
  const resultado = await radar.buscar({ termo, ...params });

  // Salvar no cache
  cache.set(cacheKey, {
    data: resultado,
    timestamp: Date.now()
  });

  return resultado;
}

Precisa de ajuda? Consulte a documentacao completa do SDK no repositorio oficial ou use nosso assistente virtual para tirar duvidas sobre a integracao.

Ainda tem dúvidas?

Converse com nosso assistente virtual especializado para obter ajuda personalizada sobre qualquer funcionalidade.

Abrir Assistente