Voltar ao blog

Como configurar um proxy para API GraphQL: rotação de IP e contorno de rate limiting com exemplos de código

Guia completo para configurar proxies para trabalhar com GraphQL API: exemplos de código, rotação de endereços IP, contorno de rate limiting e proteção contra bloqueios.

📅15 de fevereiro de 2026
```html

APIs GraphQL estão se tornando cada vez mais populares, mas junto com isso, as restrições também aumentam: rate limiting, bloqueios por IP, filtros geográficos. Se você está lidando com grandes volumes de dados através do GraphQL — extraindo dados de plataformas de e-commerce, coletando análises de redes sociais ou testando APIs — não há como evitar o uso de proxies. Neste artigo, vamos discutir como configurar corretamente um proxy para solicitações GraphQL, implementar a rotação de IP e evitar bloqueios.

Mostraremos exemplos práticos em Python e Node.js, discutiremos erros comuns e daremos recomendações sobre como escolher o tipo de proxy para diferentes tarefas.

Por que usar proxies para solicitações GraphQL

APIs GraphQL são frequentemente usadas para obter grandes volumes de dados em um curto espaço de tempo. Ao contrário das APIs REST, onde os dados estão divididos em vários endpoints, o GraphQL permite solicitar tudo o que é necessário em uma única solicitação. Isso é conveniente, mas cria problemas:

  • Rate limiting — a maioria das APIs GraphQL públicas limita o número de solicitações de um único IP (por exemplo, GitHub API: 5000 solicitações por hora, Shopify: 2 solicitações por segundo)
  • Bloqueios de IP — ao exceder os limites ou em caso de atividade suspeita, seu IP pode ser bloqueado por várias horas ou permanentemente
  • Restrições geográficas — algumas APIs estão disponíveis apenas de determinados países (por exemplo, marketplaces locais ou serviços regionais)
  • Proteção contra scraping — servidores monitoram padrões de solicitações e bloqueiam IPs suspeitos

Proxies resolvem esses problemas, permitindo distribuir solicitações através de vários endereços IP, imitar solicitações de diferentes regiões e contornar bloqueios. Isso é especialmente importante ao trabalhar com:

  • Extração de dados de plataformas de e-commerce (Shopify, WooCommerce GraphQL API)
  • Coleta de análises de redes sociais (Facebook Graph API, Instagram API)
  • Monitoramento de preços e disponibilidade de produtos
  • Testes de APIs de diferentes localizações geográficas
  • Automatização da coleta de dados para análises e pesquisas

Qual tipo de proxy escolher para trabalhar com GraphQL

A escolha do tipo de proxy depende da tarefa e dos requisitos da API. Vamos discutir três tipos principais e suas aplicações para solicitações GraphQL:

Tipo de proxy Velocidade Anonimato Quando usar
Proxies de data center Muito alta (10-50 ms) Média Extração de APIs públicas, testes, alta velocidade é mais importante que anonimato
Proxies residenciais Média (100-300 ms) Muito alta Trabalho com APIs protegidas (Shopify, Facebook), contornando filtros rigorosos
Proxies móveis Média (150-400 ms) Máxima Instagram API, TikTok API, aplicativos móveis com GraphQL

Recomendações de escolha:

  • Para APIs públicas (GitHub, OpenWeather) — proxies de data center são suficientes, são rápidos e baratos
  • Para e-commerce (Shopify, WooCommerce) — proxies residenciais, pois essas plataformas filtram ativamente os data centers
  • Para redes sociais (Facebook Graph API, Instagram) — proxies móveis ou residenciais são obrigatórios
  • Para scraping em massa — combinação: data centers para o tráfego principal + residenciais para rotação em caso de bloqueios

Configuração de proxy em Python para GraphQL (requests, httpx, gql)

Python é uma das linguagens mais populares para trabalhar com APIs. Vamos considerar três maneiras de configurar proxies para solicitações GraphQL.

Opção 1: Biblioteca requests (cliente HTTP simples)

A maneira mais simples é usar a biblioteca padrão requests. É adequada para solicitações GraphQL básicas sem lógica complexa.

import requests
import json

# Configuração do proxy
proxies = {
    'http': 'http://username:password@proxy.example.com:8080',
    'https': 'http://username:password@proxy.example.com:8080'
}

# Solicitação GraphQL
query = """
query {
  products(first: 10) {
    edges {
      node {
        id
        title
        priceRange {
          minVariantPrice {
            amount
          }
        }
      }
    }
  }
}
"""

# Enviando a solicitação através do proxy
url = "https://your-shop.myshopify.com/api/2024-01/graphql.json"
headers = {
    'Content-Type': 'application/json',
    'X-Shopify-Storefront-Access-Token': 'your_token_here',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

response = requests.post(
    url,
    json={'query': query},
    headers=headers,
    proxies=proxies,
    timeout=30
)

data = response.json()
print(json.dumps(data, indent=2))

Opção 2: Biblioteca httpx (solicitações assíncronas)

Se você precisa enviar muitas solicitações em paralelo, use httpx com suporte a async/await:

import httpx
import asyncio
import json

async def fetch_graphql(query, proxy_url):
    url = "https://api.example.com/graphql"
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
    }
    
    # Configuração do proxy para httpx
    proxies = {
        "http://": proxy_url,
        "https://": proxy_url
    }
    
    async with httpx.AsyncClient(proxies=proxies, timeout=30.0) as client:
        response = await client.post(
            url,
            json={'query': query},
            headers=headers
        )
        return response.json()

# Uso
query = """
query {
  viewer {
    login
    repositories(first: 5) {
      nodes {
        name
        stargazerCount
      }
    }
  }
}
"""

proxy = "http://user:pass@proxy.example.com:8080"
result = asyncio.run(fetch_graphql(query, proxy))
print(json.dumps(result, indent=2))

Opção 3: Biblioteca gql (cliente GraphQL especializado)

Para trabalho avançado com GraphQL, use a biblioteca gql — ela suporta validação de esquemas, cache e trabalho conveniente com solicitações:

from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport

# Configuração do transporte com proxy
transport = RequestsHTTPTransport(
    url='https://api.example.com/graphql',
    headers={
        'Authorization': 'Bearer YOUR_TOKEN',
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)'
    },
    proxies={
        'http': 'http://user:pass@proxy.example.com:8080',
        'https': 'http://user:pass@proxy.example.com:8080'
    },
    timeout=30
)

# Criação do cliente
client = Client(transport=transport, fetch_schema_from_transport=True)

# Solicitação GraphQL
query = gql("""
    query GetProducts($first: Int!) {
        products(first: $first) {
            edges {
                node {
                    id
                    title
                    variants(first: 1) {
                        edges {
                            node {
                                price
                            }
                        }
                    }
                }
            }
        }
    }
""")

# Execução da solicitação
result = client.execute(query, variable_values={"first": 20})
print(result)

Configuração de proxy em Node.js para GraphQL (axios, apollo-client)

Node.js também é amplamente utilizado para trabalhar com APIs GraphQL. Vamos considerar duas abordagens principais.

Opção 1: Axios com proxy

Um cliente HTTP simples e flexível com suporte a proxy:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

// Configuração do proxy
const proxyUrl = 'http://username:password@proxy.example.com:8080';
const httpsAgent = new HttpsProxyAgent(proxyUrl);

// Solicitação GraphQL
const query = `
  query {
    products(first: 10) {
      edges {
        node {
          id
          title
          priceRange {
            minVariantPrice {
              amount
            }
          }
        }
      }
    }
  }
`;

// Enviando a solicitação
axios.post('https://your-shop.myshopify.com/api/2024-01/graphql.json', 
  { query },
  {
    headers: {
      'Content-Type': 'application/json',
      'X-Shopify-Storefront-Access-Token': 'your_token_here',
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
    },
    httpsAgent: httpsAgent,
    timeout: 30000
  }
)
.then(response => {
  console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
  console.error('Erro:', error.message);
});

Opção 2: Apollo Client com proxy

Apollo Client é o cliente GraphQL mais popular para Node.js e navegador. Configuração de proxy através de um fetch personalizado:

const { ApolloClient, InMemoryCache, HttpLink, gql } = require('@apollo/client');
const fetch = require('cross-fetch');
const HttpsProxyAgent = require('https-proxy-agent');

// Agente de proxy
const proxyUrl = 'http://user:pass@proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);

// Fetch personalizado com proxy
const customFetch = (uri, options) => {
  return fetch(uri, {
    ...options,
    agent: agent
  });
};

// Criação do Apollo Client
const client = new ApolloClient({
  link: new HttpLink({
    uri: 'https://api.example.com/graphql',
    fetch: customFetch,
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
    }
  }),
  cache: new InMemoryCache()
});

// Solicitação GraphQL
const GET_REPOS = gql`
  query GetRepositories($login: String!) {
    user(login: $login) {
      repositories(first: 5) {
        nodes {
          name
          stargazerCount
        }
      }
    }
  }
`;

// Execução da solicitação
client.query({
  query: GET_REPOS,
  variables: { login: 'facebook' }
})
.then(result => {
  console.log(JSON.stringify(result.data, null, 2));
})
.catch(error => {
  console.error('Erro:', error);
});

Implementação de rotação de proxies para contornar rate limiting

A rotação de proxies é uma técnica chave para contornar as restrições da API. Em vez de enviar todas as solicitações de um único IP, você as distribui entre vários proxies. Isso permite contornar o rate limiting e evitar bloqueios.

Rotação simples em Python

Implementação básica de rotação com alternância cíclica de proxies:

import requests
import itertools
import time

# Lista de proxies
PROXY_LIST = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
    'http://user:pass@proxy4.example.com:8080',
]

# Criando um iterador infinito
proxy_pool = itertools.cycle(PROXY_LIST)

def make_graphql_request(query):
    """Enviando uma solicitação GraphQL com rotação de proxies"""
    proxy = next(proxy_pool)
    proxies = {'http': proxy, 'https': proxy}
    
    url = "https://api.example.com/graphql"
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
    }
    
    try:
        response = requests.post(
            url,
            json={'query': query},
            headers=headers,
            proxies=proxies,
            timeout=30
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"Erro com o proxy {proxy}: {e}")
        # Alternando para o próximo proxy
        return make_graphql_request(query)

# Exemplo de uso
queries = [
    'query { products(first: 10) { edges { node { id title } } } }',
    'query { collections(first: 5) { edges { node { id title } } } }',
    'query { shop { name email } }'
]

for query in queries:
    result = make_graphql_request(query)
    print(result)
    time.sleep(1)  # Pausa entre as solicitações

Rotação inteligente com rastreamento de erros

Uma versão mais avançada que rastreia proxies não funcionais e os exclui automaticamente do pool:

import requests
import random
from collections import defaultdict
import time

class ProxyRotator:
    def __init__(self, proxy_list, max_failures=3):
        self.proxy_list = proxy_list.copy()
        self.max_failures = max_failures
        self.failures = defaultdict(int)
        self.active_proxies = proxy_list.copy()
    
    def get_proxy(self):
        """Obter um proxy ativo aleatório"""
        if not self.active_proxies:
            raise Exception("Todos os proxies estão indisponíveis!")
        return random.choice(self.active_proxies)
    
    def mark_failure(self, proxy):
        """Marcar uma tentativa falha"""
        self.failures[proxy] += 1
        if self.failures[proxy] >= self.max_failures:
            print(f"Proxy {proxy} excluído do pool (limite de erros excedido)")
            if proxy in self.active_proxies:
                self.active_proxies.remove(proxy)
    
    def mark_success(self, proxy):
        """Redefinir o contador de erros em caso de sucesso"""
        self.failures[proxy] = 0

# Inicialização
proxies = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080',
]

rotator = ProxyRotator(proxies)

def graphql_request_with_retry(query, max_retries=3):
    """Solicitação GraphQL com tentativas automáticas"""
    for attempt in range(max_retries):
        proxy = rotator.get_proxy()
        proxies_dict = {'http': proxy, 'https': proxy}
        
        try:
            response = requests.post(
                'https://api.example.com/graphql',
                json={'query': query},
                headers={
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer TOKEN',
                    'User-Agent': 'Mozilla/5.0'
                },
                proxies=proxies_dict,
                timeout=30
            )
            response.raise_for_status()
            
            # Sucesso — redefinindo o contador de erros
            rotator.mark_success(proxy)
            return response.json()
            
        except Exception as e:
            print(f"Tentativa {attempt + 1}/{max_retries} com {proxy} falhou: {e}")
            rotator.mark_failure(proxy)
            time.sleep(2)  # Pausa antes da repetição
    
    raise Exception("Não foi possível executar a solicitação após todas as tentativas")

# Uso
query = 'query { products(first: 10) { edges { node { id title } } } }'
result = graphql_request_with_retry(query)
print(result)

Configuração de cabeçalhos e User-Agent para solicitações GraphQL

Os cabeçalhos HTTP corretos são críticos para o sucesso ao trabalhar com APIs GraphQL através de proxies. Muitas APIs verificam não apenas o IP, mas também os cabeçalhos da solicitação.

Cabeçalhos obrigatórios para GraphQL

headers = {
    # Tipo de conteúdo — sempre application/json para GraphQL
    'Content-Type': 'application/json',
    
    # Autorização (depende da API)
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    # ou
    'X-Shopify-Storefront-Access-Token': 'token_here',
    
    # User-Agent — imitando um navegador real
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    
    # Accept — indicando que aceitamos JSON
    'Accept': 'application/json',
    
    # Accept-Language — idioma do usuário
    'Accept-Language': 'en-US,en;q=0.9',
    
    # Accept-Encoding — suporte à compressão
    'Accept-Encoding': 'gzip, deflate, br',
    
    # Referer — de onde a solicitação veio (opcional)
    'Referer': 'https://example.com/',
    
    # Origin — para solicitações CORS
    'Origin': 'https://example.com'
}

Rotação de User-Agent

Para maior anonimato, recomenda-se rotacionar o User-Agent junto com o proxy:

import random

USER_AGENTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15'
]

def get_random_headers(token):
    """Geração de cabeçalhos aleatórios"""
    return {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {token}',
        'User-Agent': random.choice(USER_AGENTS),
        'Accept': 'application/json',
        'Accept-Language': 'en-US,en;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br'
    }

Tratamento de erros e tentativas através de proxies

Ao trabalhar com proxies, erros são inevitáveis: timeouts, proxies indisponíveis, bloqueios. É importante tratar essas situações corretamente e implementar um mecanismo de tentativas.

Erros comuns do GraphQL através de proxies

  • Timeouts — proxy lento ou sobrecarregado (aumente o timeout para 30-60 segundos)
  • HTTP 407 Proxy Authentication Required — login/senha do proxy incorretos
  • HTTP 429 Too Many Requests — limite de taxa excedido (necessita de rotação de proxies)
  • HTTP 403 Forbidden — IP do proxy bloqueado (mude o tipo de proxy para residenciais)
  • Connection refused — proxy indisponível (exclua do pool)

Tratamento avançado de erros

import requests
import time
from requests.exceptions import ProxyError, Timeout, ConnectionError

def graphql_request_robust(query, proxy, max_retries=3, backoff=2):
    """
    Solicitação GraphQL confiável com tratamento de todos os tipos de erros
    
    Args:
        query: Solicitação GraphQL
        proxy: URL do proxy
        max_retries: máximo de tentativas
        backoff: multiplicador de atraso entre tentativas
    """
    url = "https://api.example.com/graphql"
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer TOKEN',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
    }
    proxies = {'http': proxy, 'https': proxy}
    
    for attempt in range(max_retries):
        try:
            response = requests.post(
                url,
                json={'query': query},
                headers=headers,
                proxies=proxies,
                timeout=30
            )
            
            # Verificação de rate limiting
            if response.status_code == 429:
                retry_after = int(response.headers.get('Retry-After', 60))
                print(f"Limite de taxa! Aguardando {retry_after} segundos...")
                time.sleep(retry_after)
                continue
            
            # Verificação de bloqueio de IP
            if response.status_code == 403:
                print(f"IP {proxy} bloqueado! Precisa de outro proxy.")
                raise Exception("IP bloqueado")
            
            # Verificação de erros de autenticação do proxy
            if response.status_code == 407:
                print(f"Erro de autenticação do proxy {proxy}")
                raise Exception("Falha na autenticação do proxy")
            
            response.raise_for_status()
            
            # Verificação de erros do GraphQL
            data = response.json()
            if 'errors' in data:
                print(f"Erros do GraphQL: {data['errors']}")
                # Alguns erros podem ser repetidos, outros não
                if is_retryable_graphql_error(data['errors']):
                    time.sleep(backoff * (attempt + 1))
                    continue
                else:
                    raise Exception(f"Erro do GraphQL: {data['errors']}")
            
            return data
            
        except (ProxyError, ConnectionError) as e:
            print(f"Tentativa {attempt + 1}: Proxy indisponível - {e}")
            time.sleep(backoff * (attempt + 1))
            
        except Timeout as e:
            print(f"Tentativa {attempt + 1}: Timeout - {e}")
            time.sleep(backoff * (attempt + 1))
            
        except requests.exceptions.HTTPError as e:
            print(f"Tentativa {attempt + 1}: Erro HTTP - {e}")
            if attempt < max_retries - 1:
                time.sleep(backoff * (attempt + 1))
            else:
                raise
    
    raise Exception(f"Não foi possível executar a solicitação após {max_retries} tentativas")

def is_retryable_graphql_error(errors):
    """Determina se a solicitação pode ser repetida em caso de erro do GraphQL"""
    retryable_codes = ['THROTTLED', 'INTERNAL_ERROR', 'TIMEOUT']
    for error in errors:
        if error.get('extensions', {}).get('code') in retryable_codes:
            return True
    return False

Melhores práticas para trabalhar com GraphQL através de proxies

Vamos resumir e dar recomendações para um trabalho eficaz com APIs GraphQL através de proxies:

✓ Otimização de solicitações

  • Solicite apenas os campos necessários — o GraphQL permite especificar exatamente o que é preciso
  • Use paginação em vez de solicitar todos os dados de uma vez
  • Agrupe solicitações relacionadas em uma só (o GraphQL suporta solicitações múltiplas)
  • Cache os resultados do lado do cliente para reduzir o número de solicitações

✓ Gerenciamento de proxies

  • Use um pool de pelo menos 5-10 proxies para rotação
  • Verifique regularmente a funcionalidade dos proxies (health check)
  • Exclua automaticamente proxies não funcionais do pool
  • Para tarefas críticas, mantenha proxies de reserva de outro tipo

✓ Cumprimento de limites

  • Estude a documentação da API — lá estão os limites exatos
  • Adicione atrasos entre solicitações (1-2 segundos no mínimo)
  • Monitore os cabeçalhos X-RateLimit-Remaining e X-RateLimit-Reset
  • Ao receber erros 429, aumente o atraso exponencialmente

✓ Segurança e anonimato

  • Use sempre proxies HTTPS para proteger tokens de autorização
  • Rotacione o User-Agent junto com o proxy
  • Não armazene tokens no código — use variáveis de ambiente
  • Registre apenas as informações mínimas necessárias

Arquitetura recomendada para projetos em larga escala

Se você está lidando com grandes volumes de dados, recomendamos a seguinte arquitetura:

  1. Fila de tarefas (Redis, RabbitMQ) — para distribuir solicitações entre trabalhadores
  2. Pool de trabalhadores — cada trabalhador usa seu próprio proxy
  3. Gerenciador de proxies — monitora o estado dos proxies e os distribui entre os trabalhadores
  4. Banco de dados — para armazenar resultados e estados de tarefas
  5. Monitoramento — rastreamento de erros, velocidade, uso de proxies

Conclusão

Trabalhar com APIs GraphQL através de proxies não é apenas adicionar o parâmetro proxies na solicitação. Para um funcionamento confiável e eficaz, é necessário implementar a rotação de proxies, o tratamento correto de erros, configurar cabeçalhos e respeitar os limites da API. Discutimos exemplos práticos em Python e Node.js que podem ser usados imediatamente em seus projetos.

Principais conclusões: use proxies residenciais para APIs protegidas (Shopify, Facebook), data centers para APIs públicas e scraping em massa, implemente rotação automática excluindo proxies não funcionais, adicione atrasos e trate todos os tipos de erros. Isso permitirá que você trabalhe de forma estável com qualquer API GraphQL sem bloqueios.

Se você planeja trabalhar com APIs GraphQL em produção, recomendamos o uso de proxies residenciais — eles oferecem máxima estabilidade e mínimo risco de bloqueios. Para testes e desenvolvimento, proxies de data center são adequados — eles são mais rápidos e baratos.

```