As APIs são uma ótima maneira para aplicativos de software se comunicarem entre si. Elas permitem que aplicativos interajam e compartilhem recursos ou privilégios.

Atualmente, muitas empresas B2B oferecem seus serviços por meio de APIs que podem ser consumidas por aplicativos desenvolvidos em qualquer linguagem de programação e framework. No entanto, isso as torna vulneráveis a ataques de DoS e DDoS, além de poder causar uma distribuição desigual de largura de banda entre os usuários. Para lidar com esses problemas, é implementada uma técnica conhecida como limitação de taxa API. A ideia é simples: você limita o número de solicitações que os usuários podem fazer à sua API.

Neste guia, você aprenderá o que é limitação de taxa API, as várias maneiras de implementá-la e algumas práticas recomendadas e exemplos a serem lembrados ao configurar limites de taxa API.

O que é limitação de taxa API?

Em palavras simples, a limitação de taxa API refere-se à definição de um limite sobre o número de vezes que uma API pode ser acessada por seus usuários. Os limites podem ser decididos de várias maneiras.

1. Limites baseados no usuário

Uma das maneiras de definir um limite de taxa é reduzir o número de vezes que um determinado usuário pode acessar a API em um determinado período de tempo. Isso pode ser feito contando o número de solicitações feitas usando a mesma chave de API ou endereço IP e, quando um limite é atingido, outras solicitações são limitadas ou negadas.

2. Limites baseados em localização

Em muitos casos, os desenvolvedores desejam distribuir a largura de banda disponível para sua API igualmente entre determinadas localizações geográficas.

O recente serviço de visualização do ChatGPT é um bom exemplo de limitação de taxa baseada em localização, pois começaram a limitar as solicitações com base nas localizações dos usuários na versão gratuita do serviço assim que a versão paga foi lançada. Isso fazia sentido, pois a versão de visualização gratuita deveria ser usada por pessoas de todo o mundo para gerar uma boa amostra de dados de uso para o serviço.

3. Limites baseados no servidor

A limitação de taxa baseada no servidor é uma limitação interna implementada no lado do servidor para garantir uma distribuição equitativa dos recursos do servidor, como CPU, memória, espaço em disco, etc. Isso é feito implementando um limite em cada servidor de uma implantação.

Quando um servidor atinge seu limite, outras solicitações de entrada são encaminhadas para outro servidor com capacidade disponível. Se todos os servidores atingirem a capacidade, o usuário receberá uma resposta 429 Too Many Requests. É importante observar que os limites de taxa baseados no servidor são aplicados a todos os clientes, independentemente de sua localização geográfica, horário de acesso ou outros fatores.

Tipos de limites de taxa API

Além da natureza da implementação dos limites de taxa, você também pode classificá-los com base em seu efeito no usuário final. Alguns tipos comuns são:

  • Limites rígidos: São limites rígidos que, quando ultrapassados, restringem completamente o acesso do usuário ao recurso até que o limite seja suspenso.
  • Limites flexíveis: São limites flexíveis que, quando ultrapassados, ainda podem permitir que o usuário acesse o recurso mais algumas vezes (ou diminuam as solicitações) antes de interromper o acesso.
  • Limites dinâmicos: Esses limites dependem de múltiplos fatores, como carga do servidor, tráfego de rede, localização do usuário, atividade do usuário, distribuição de tráfego, etc., sendo alterados em tempo real para o funcionamento eficiente dos recursos.
  • Controle de fluxo: Esses limites não interrompem o acesso ao recurso, mas sim reduzem a velocidade ou enfileiram as solicitações recebidas até que o limite seja suspenso.
  • Limites tarifáveis: Esses limites não restringem o acesso nem diminuem a velocidade, mas cobram do usuário por novas solicitações quando o limite gratuito definido é excedido.

Por que a limitação de taxa é necessária?

Existem várias razões pelas quais você precisa implementar a limitação de taxa em suas APIs da Web. Alguns dos principais motivos são:

1. Proteção do acesso a recursos

O primeiro motivo pelo qual você deve considerar a implementação de um limite de taxa API em seu aplicativo é para proteger seus recursos contra a exploração excessiva por usuários com intenções mal-intencionadas. Os invasores podem usar técnicas como ataques DDoS para monopolizar o acesso aos seus recursos e impedir que o aplicativo funcione normalmente para outros usuários. Ter um limite de taxa em vigor garante que você não esteja facilitando a interrupção de suas APIs pelos invasores.

2. Divisão da cota entre os usuários

Além de proteger os seus recursos, o limite de taxa permite que você divida os recursos da API entre os usuários. Isso significa que você pode criar modelos de preços diferenciados e atender às necessidades dinâmicas dos seus clientes sem permitir que elas afetem outros clientes.

3. Aumento da eficiência de custos

A limitação de taxas também equivale à limitação de custos. Isso significa que você pode fazer uma distribuição criteriosa dos seus recursos entre os usuários. Com uma estrutura particionada, é mais fácil estimar o custo necessário para a manutenção do sistema. Quaisquer picos podem ser tratados de forma inteligente, provisionando ou desativando a quantidade certa de recursos.

4. Gerenciamento do fluxo entre os workers

Muitas APIs dependem de uma arquitetura distribuída que usa vários workers/threads/instâncias para lidar com as solicitações recebidas. Nessa estrutura, você pode usar limites de taxa para controlar a carga de trabalho passada para cada worker node. Isso pode ajudar você a garantir que os worker nodes recebam workloads equitativas e sustentáveis. Você pode adicionar ou remover workers com facilidade, quando necessário, sem reestruturar todo o gateway da API.

Entendendo os limites de burst

Outra forma comum de controlar o uso de uma API é definir um limite de burst (também conhecido como throttling) em vez de um limite de taxa. Os limites de burst são limites de taxa implementados para um intervalo de tempo muito curto, como alguns segundos. Por exemplo, em vez de estabelecer um limite de 1,3 milhão de solicitações por mês, você pode definir um limite de 5 solicitações por segundo. Embora isso resulte no mesmo limite de tráfego mensal, ele garante que seus clientes não sobrecarreguem seus servidores enviando milhares de solicitações de uma só vez.

No caso dos limites de burst, as solicitações são geralmente atrasadas até o próximo intervalo em vez de serem negadas completamente. Geralmente, é recomendado usar tanto limites de taxa quanto de burst juntos para um controle ótimo de tráfego e uso.

3 métodos de implementação da limitação de taxa

Quando se trata de implementação, há alguns métodos que você pode usar para configurar a limitação de taxa API em seu aplicativo. Eles incluem:

1. Filas de solicitações

Um dos métodos mais simples e práticos de restringir o acesso à API é por meio de filas de solicitações. As filas de solicitações referem-se a um mecanismo no qual as solicitações recebidas são armazenadas em uma fila e processadas uma após a outra até um determinado limite.

Um caso de uso comum de filas de solicitações é a separação de solicitações recebidas de usuários gratuitos e pagos. Veja como você pode fazer isso em um aplicativo Express usando o pacote express-queue:

const express = require('express')
const expressQueue = require('express-queue');

const app = express()

const freeRequestsQueue = expressQueue({
    activeLimit: 1, // Maximum requests to process at once
    queuedLimit: -1 // Maximum requests allowed in queue (-1 means unlimited)
});

const paidRequestsQueue = expressQueue({
    activeLimit: 5, // Maximum requests to process at once
    queuedLimit: -1 // Maximum requests allowed in queue (-1 means unlimited)
});

// Middleware that selects the appropriate queue handler based on the presence of an API token in the request
function queueHandlerMiddleware(req, res, next) {
    // Check if the request contains an API token
    const apiToken = req.headers['api-token'];

    if (apiToken && isValidToken(apiToken)) {
        console.log("Paid request received")
        paidRequestsQueue(req, res, next);
    } else {
        console.log("Free request received")
        freeRequestsQueue(req, res, next);
     }
}

// Add the custom middleware function to the route
app.get('/route', queueHandlerMiddleware, (req, res) => {
    res.status(200).json({ message: "Processed!" })
});

// Check here is the API token is valid or not
const isValidToken = () => {
    return true;
}

app.listen(3000);

2. Throttling

O throttling é outra técnica usada para controlar o acesso às APIs. Em vez de interromper o acesso após atingir um limite, o throttling tem como objetivo nivelar os picos no tráfego da API, implementando pequenos limites para pequenos intervalos de tempo. Em vez de definir um limite de taxa, como 3 milhões de chamadas por mês, o throttling estabelece limites de 10 chamadas por segundo. Uma vez que um cliente envia mais de 10 chamadas em um segundo, as próximas solicitações no mesmo segundo são automaticamente limitadas, mas o cliente recupera instantaneamente o acesso à API no próximo segundo.

Você pode implementar o throttling no Express usando o pacote express-throttle. Aqui está um exemplo de um aplicativo Express que mostra como configurar o throttling em seu aplicativo:

const express = require('express')
const throttle = require('express-throttle')

const app = express()

const throttleOptions = {
    "rate": "10/s",
    "burst": 5,
    "on_allowed": function (req, res, next, bucket) {
        res.set("X-Rate-Limit-Limit", 10);
        res.set("X-Rate-Limit-Remaining", bucket.tokens);
        next()
    },
    "on_throttled": function (req, res, next, bucket) {
        // Notify client
        res.set("X-Rate-Limit-Limit", 10);
        res.set("X-Rate-Limit-Remaining", 0);
        res.status(503).send("System overloaded, try again after a few seconds.");
    }
}

// Add the custom middleware function to the route
app.get('/route', throttle(throttleOptions), (req, res) => {
    res.status(200).json({ message: "Processed!" })
});

app.listen(3000);

Você pode testar o aplicativo usando uma ferramenta de teste de carga como o AutoCannon. Você pode instalar o AutoCannon executando o seguinte comando em seu terminal:

npm install autocannon -g

Você pode testar o aplicativo usando o seguinte:

autocannon http://localhost:3000/route

O teste usa 10 conexões simultâneas que enviam solicitações à API. Aqui está o resultado do teste:

Running 10s test @ http://localhost:3000/route

10 connections

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max   │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 0 ms │ 0 ms │ 1 ms  │ 1 ms │ 0.04 ms │ 0.24 ms │ 17 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬────────┬─────────┬────────┬─────────┬─────────┐
│ Stat      │ 1%      │ 2.5%    │ 50%    │ 97.5%   │ Avg    │ Stdev   │ Min     │
├───────────┼─────────┼─────────┼────────┼─────────┼────────┼─────────┼─────────┤
│ Req/Sec   │ 16591   │ 16591   │ 19695  │ 19903   │ 19144  │ 1044.15 │ 16587   │
├───────────┼─────────┼─────────┼────────┼─────────┼────────┼─────────┼─────────┤
│ Bytes/Sec │ 5.73 MB │ 5.73 MB │ 6.8 MB │ 6.86 MB │ 6.6 MB │ 360 kB  │ 5.72 MB │
└───────────┴─────────┴─────────┴────────┴─────────┴────────┴─────────┴─────────┘

Req/Bytes counts sampled once per second.
# of samples: 11
114 2xx responses, 210455 non 2xx responses
211k requests in 11.01s, 72.6 MB read

Como apenas 10 solicitações por segundo foram permitidas (com uma explosão extra de 5 solicitações), apenas 114 solicitações foram processadas com êxito pela API, e as solicitações restantes foram respondidas com um código de erro 503 pedindo que você aguardasse algum tempo.

3. Algoritmos de limitação de taxa

Embora a limitação de taxa pareça um conceito simples que pode ser implementado usando uma fila, ela pode, de fato, ser implementada de várias maneiras, oferecendo vários benefícios. Aqui estão alguns algoritmos populares usados para implementar a limitação de taxa:

Algoritmo da janela fixa (Fixed Window Algorithm)

O algoritmo de janela fixa é um dos algoritmos de limitação de taxa mais simples. Ele limita o número de solicitações que podem ser tratadas em um intervalo de tempo fixo.

Você define um número fixo de solicitações, digamos 100, que podem ser processadas pelo servidor de API em uma hora. Agora, quando a 101ª solicitação chegar, o algoritmo se recusará a processá-la. Quando o intervalo de tempo for redefinido (ou seja, na próxima hora), outras 100 solicitações recebidas poderão ser processadas.

Este algoritmo é fácil de implementar e funciona bem em muitos casos em que é necessário limitar a taxa no lado do servidor para controlar a largura de banda (em contraste com a distribuição da largura de banda entre os usuários). No entanto, pode resultar em tráfego/processamento instável nos limites do intervalo de tempo fixo. O algoritmo da janela deslizante é uma alternativa melhor em casos em que é necessário um processamento uniforme.

Algoritmo da janela deslizante (Sliding Window Algorithm)

O algoritmo da janela deslizante é uma variação do algoritmo da janela fixa. Em vez de usar intervalos de tempo fixos predefinidos, esse algoritmo usa uma janela de tempo deslizante para rastrear o número de solicitações processadas e recebidas.

Em vez de analisar os intervalos de tempo absolutos (por exemplo, 60 segundos cada), como 0s a 60s, 61s a 120s, e assim por diante, o algoritmo da janela deslizante analisa os 60 segundos anteriores ao recebimento de uma solicitação. Digamos que uma solicitação seja recebida no 82º segundo; então, o algoritmo contará o número de solicitações processadas entre o 22º segundo e o 82º segundo (em vez do intervalo absoluto de 60s a 120s) para determinar se esta solicitação pode ser processada ou não. Isso pode evitar situações em que um grande número de solicitações é processado tanto no 59º quanto no 61º segundo, sobrecarregando o servidor por um período muito curto.

Este algoritmo é melhor para lidar com tráfego de rajada de forma mais fácil, mas pode ser mais difícil de implementar e manter em comparação com o algoritmo da janela fixa.

Algoritmo do bucket de tokens (Token Bucket Algorithm)

Nesse algoritmo, um bucket fictício é preenchido com tokens e, sempre que o servidor processa uma solicitação, um token é retirado do bucket. Quando o bucket está vazio, nenhuma outra solicitação pode ser processada pelo servidor. Outras solicitações são adiadas ou negadas até que o bucket seja reabastecido.

O bucket de tokens é reabastecido a uma taxa fixa (conhecida como taxa de geração de tokens), e o número máximo de tokens que podem ser armazenados no bucket também é fixo (conhecido como profundidade do bucket).

Ao controlar a taxa de regeneração de tokens e a profundidade do intervalo, você pode controlar a taxa máxima de fluxo de tráfego permitida pela API. O pacote express-throttle que você viu anteriormente usa o algoritmo de token bucket para limitar ou controlar o fluxo de tráfego da API.

A maior vantagem desse algoritmo é que ele suporta o tráfego de explosão, desde que possa ser acomodado na profundidade do bucket. Isso é especialmente útil para tráfego imprevisível.

Algoritmo de balde com vazamento (Leaky Bucket Algorithm)

O algoritmo de balde com vazamento é outro algoritmo para lidar com o tráfego de API. Em vez de manter uma profundidade do balde que determina quantas solicitações podem ser tratadas em um período de tempo (como em um bucket de token), ele permite um fluxo fixo de solicitações do balde, que é análogo ao fluxo constante de água de um balde com vazamento.

A profundidade do balde, nesse caso, é usada para determinar quantas solicitações podem ser colocadas na fila para serem processadas antes que o balde comece a transbordar, ou seja, a negar as solicitações recebidas.

O balde com vazamento promete um fluxo constante de solicitações e, ao contrário do bucket com token, não lida com picos de tráfego.

Práticas recomendadas para limitação de taxa API

Agora que você já sabe o que é limitação de taxa API e como ela é implementada. Aqui estão algumas práticas recomendadas que você deve considerar ao implementá-lo em seu aplicativo.

Ofereça um nível gratuito para os usuários explorarem seus serviços

Ao considerar a implementação de um limite de taxa API, tente sempre oferecer um nível gratuito adequado que os usuários em perspectiva possam usar para experimentar sua API. Não precisa ser muito generoso, mas deve ser suficiente para permitir que eles testem sua API confortavelmente no aplicativo de desenvolvimento.

Embora os limites de taxa da API sejam vitais para manter a qualidade dos pontos de extremidade da API para os usuários, uma pequena camada gratuita sem limitação pode ajudar você a conquistar novos usuários.

Decida o que acontece quando o limite de taxa é excedido

Quando um usuário excede o limite de taxa API definido, há alguns cuidados que você deve tomar para garantir uma experiência positiva para o usuário e, ao mesmo tempo, proteger seus recursos. Algumas perguntas que você deve fazer e considerações que deve fazer são:

Qual código de erro e mensagem seus usuários verão?

A primeira coisa que você deve cuidar é informar aos usuários que eles excederam o limite de taxa de API definido. Para fazer isso, você precisa alterar a resposta da API para uma mensagem predefinida que explique o problema. É importante que o código de status para essa resposta seja 429 “Too Many Requests” (Muitas solicitações). Também é comum explicar o problema no corpo da resposta. Veja como pode ser o corpo de resposta de exemplo:

{
    "error": "Too Many Requests",
    "message": "You have exceeded the set API rate limit of X requests per minute. Please try again in a few minutes.",
    "retry_after": 60
}

O exemplo de corpo de resposta mostrado acima menciona o nome e a descrição do erro e também especifica uma duração (geralmente em segundos) após a qual o usuário pode tentar enviar solicitações novamente. Um corpo de resposta descritivo como esse ajuda os usuários a entender o que deu errado e por que eles não receberam a resposta que esperavam. Isso também permite que eles saibam quanto tempo devem esperar antes de enviar outra solicitação.

As novas solicitações serão limitadas ou interrompidas completamente?

Outro ponto de decisão é o que fazer depois que um usuário ultrapassa o limite de taxa API definido. Normalmente, você impediria o usuário de interagir com o servidor enviando uma resposta 429 “Too Many Requests” (Muitas solicitações), como você viu acima. No entanto, você também deve considerar uma abordagem alternativa: throttling.

Em vez de interromper completamente o acesso ao recurso do servidor, você pode reduzir a velocidade do número total de solicitações que o usuário pode enviar em um determinado período de tempo. Isso é útil quando você deseja dar um pequeno aviso aos usuários, mas ainda permitir que eles continuem trabalhando se reduzirem o volume de solicitações.

Considere o cache e o circuit breaking

Os limites de taxa API são desagradáveis: eles restringem a interação e o uso dos serviços de API pelos usuários. Isso é ainda pior para os usuários que precisam fazer solicitações semelhantes repetidas vezes, como acessar um conjunto de dados de previsão do tempo que é atualizado apenas semanalmente ou buscar uma lista de opções para um menu suspenso que pode ser alterado uma vez por outra. Nesses casos, uma abordagem inteligente seria implementar o armazenamento em cache.

O armazenamento em cache é uma abstração de armazenamento de alta velocidade implementada nos casos em que o volume de acesso aos dados é alto, mas os dados não são alterados com muita frequência. Em vez de fazer uma chamada de API que pode invocar vários serviços internos e incorrer em despesas pesadas, você pode armazenar em cache os pontos de extremidade usados com mais frequência para que a segunda solicitação em diante seja atendida a partir do cache estático, o que geralmente é mais rápido, mais barato e pode reduzir a carga de trabalho dos seus serviços principais.

Pode haver outro caso em que você receba um número excepcionalmente alto de solicitações de um usuário. Mesmo após definir um limite de taxa, eles estão constantemente atingindo sua capacidade e sendo limitados pela taxa. Essas situações indicam que há uma chance de possível abuso da API.

Para proteger seus serviços contra sobrecarga e manter uma experiência uniforme para o restante dos usuários, você deve considerar restringir completamente o acesso do usuário suspeito à API. Isso é conhecido como circuit breaking e, embora pareça semelhante à limitação de taxa, é geralmente usado quando o sistema enfrenta uma sobrecarga de solicitações e precisa de tempo para desacelerar e recuperar a qualidade do serviço.

Monitore sua configuração de perto

Embora os limites de taxa API tenham o objetivo de distribuir seus recursos de forma equitativa entre os usuários, às vezes eles podem causar problemas desnecessários aos usuários ou até mesmo indicar atividades suspeitas.

Configurar uma solução de monitoramento robusta para sua API pode ajudá-lo a entender com que frequência os limites de taxa são atingidos pelos usuários, se você precisa reconsiderar os limites gerais levando em consideração a carga de trabalho média de seus usuários, e identificar usuários que frequentemente atingem seus limites (o que poderia indicar que eles possivelmente precisarão de um aumento em seus limites em breve ou que precisam ser monitorados por atividade suspeita). Em qualquer caso, uma configuração de monitoramento ativo ajudará você a entender melhor o impacto de seus limites de taxa de API.

Implemente a limitação de taxa em múltiplas camadas

A limitação de taxa pode ser implementada em vários níveis (usuário, aplicativo ou sistema). Muitas pessoas cometem o erro de configurar limites de taxa em apenas um desses níveis e esperam que isso cubra todos os casos possíveis. Embora não seja exatamente um anti-padrão, pode se revelar ineficaz em alguns casos.

Se as solicitações recebidas sobrecarregarem a interface de rede do seu sistema, a limitação de taxa no nível do aplicativo pode não ser capaz de otimizar as cargas de trabalho. Portanto, é melhor configurar as regras de limitação de taxa em mais de um nível, preferencialmente nas camadas mais altas de sua arquitetura, para garantir que não sejam criados gargalos.

Como trabalhar com limites de taxa API

Nesta seção, você aprenderá como testar os limites de taxa API para um determinado endpoint de API e como implementar um controle de uso no seu cliente para garantir que você não acabe esgotando os limites da API remota.

Como testar os limites de taxa de uma API

Para identificar o limite de taxa de uma API, sua primeira abordagem deve sempre ser ler a documentação da API para identificar se os limites foram claramente definidos. Geralmente, a documentação da API informará o limite e como ele foi implementado. Você deve recorrer à “teste” do limite de taxa da API apenas quando não puder identificá-lo na documentação da API, no suporte ou na comunidade. Isso ocorre porque testar uma API para encontrar seu limite de taxa significa que você acabará esgotando seu limite de taxa pelo menos uma vez, o que pode incorrer em custos financeiros e/ou na indisponibilidade da API por um determinado período.

Se você deseja identificar manualmente o limite de taxa, deve começar com uma ferramenta simples de teste de API, como o Postman, para fazer solicitações manualmente à API e verificar se consegue esgotar o limite de taxa. Se não conseguir, pode usar uma ferramenta de teste de carga, como Autocannon ou Gatling, para simular um grande número de solicitações e ver quantas solicitações são processadas pela API antes de ela começar a responder com o código de status 429.

Outra abordagem pode ser usar uma ferramenta de verificação de limite de taxa, como o AppBrokers’ rate-limit-test-tool. Ferramentas dedicadas como essa automatizam o processo para você e também fornecem uma interface de usuário para analisar cuidadosamente os resultados do teste.

No entanto, se não tiver certeza do limite de taxa de uma API, você sempre pode tentar estimar os requisitos de solicitação e configurar limites no lado do cliente para garantir que o número de solicitações do seu aplicativo não exceda esse número. Você aprenderá como fazer isso na próxima seção.

Como limitar chamadas de API (Throttle)

Se você está fazendo chamadas para uma API a partir do seu código, pode ser interessante implementar limites no seu lado para garantir que você não acabe fazendo chamadas demais para a API e excedendo o limite permitido. Existem várias maneiras de fazer isso. Uma das formas populares é usar o método throttle na biblioteca de utilitários lodash.

Antes de começar a limitar uma chamada de API, você precisará criar uma API. Aqui está um código de exemplo para uma API baseada em Node.js que imprime o número médio de solicitações que recebe por minuto no console:

const express = require('express');
const app = express();

// maintain a count of total requests
let requestTotalCount = 0;
let startTime = Date.now();

// increase the count whenever any request is received
app.use((req, res, next) => {
    requestTotalCount++;
    next();
});

// After each second, print the average number of requests received per second since the server was started
setInterval(() => {
    const elapsedTime = (Date.now() - startTime) / 1000;
    const averageRequestsPerSecond = requestTotalCount / elapsedTime;
    console.log(`Average requests per second: ${averageRequestsPerSecond.toFixed(2)}`);
}, 1000);

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('Server listening on port 3000!');
});

Quando esse aplicativo for executado, ele imprimirá o número médio de solicitações recebidas a cada segundo:

Average requests per second: 0
Average requests per second: 0
Average requests per second: 0

Em seguida, crie um novo arquivo JavaScript com o nome test-throttle.js e salve o seguinte código nele:

// function that calls the API and prints the response
const request = () => {
    fetch('http://localhost:3000')
    .then(r => r.text())
    .then(r => console.log(r))
}

// Loop to call the request function once every 100 ms, i.e., 10 times per second
setInterval(request, 100)

Após executar esse script, você perceberá que o número médio de solicitações para o servidor salta para perto de 10:

Average requests per second: 9.87
Average requests per second: 9.87
Average requests per second: 9.88

E se essa API permitir apenas 6 solicitações por segundo, por exemplo? Você desejará manter a contagem média de solicitações abaixo desse limite. No entanto, se seu cliente enviar uma solicitação com base em alguma atividade do usuário, como o clique de um botão ou uma rolagem, talvez você não consiga limitar o número de vezes que a chamada de API é acionada.

Nesse caso, a função throttle() do lodash pode ajudar. Antes de tudo, instale a biblioteca executando o seguinte comando:

npm install lodash

Em seguida, atualize o arquivo test-throttle.js para que ele contenha o seguinte código:

// import the lodash library
const { throttle } = require('lodash');

// function that calls the API and prints the response
const request = () => {
    fetch('http://localhost:3000')
    .then(r => r.text())
    .then(r => console.log(r))
}

// create a throttled function that can only be called once every 200 ms, i.e., only 5 times every second
const throttledRequest = throttle(request, 200)

// loop this throttled function to be called once every 100 ms, i.e., 10 times every second
setInterval(throttledRequest, 100)

Agora, se você observar os registros do servidor, verá uma saída semelhante:

Average requests per second: 4.74
Average requests per second: 4.80
Average requests per second: 4.83

Isso significa que, mesmo que seu aplicativo esteja chamando a função request de solicitação 10 vezes a cada segundo, a função throttle garante que ela seja chamada apenas 5 vezes por segundo, ajudando você a ficar dentro do limite de taxa. É assim que você pode configurar o throttling no lado do cliente para evitar exceder os limites de taxa da API.

Erros comuns de limitação de taxa API

Ao trabalhar com APIs com limite de taxa, você pode encontrar uma variedade de respostas que indicam quando um limite de taxa foi excedido. Geralmente, você receberá o código de status 429 com uma mensagem semelhante a uma destas:

  • Chamadas para esta API excederam o limite de taxa
  • Limite de taxa da API excedido
  • 429 Too Many Requests

No entanto, a mensagem que você recebe depende da implementação da API que você está usando. Essa implementação pode variar, e algumas APIs podem nem usar o código de status 429. Aqui estão outros tipos de códigos e mensagens de erro de limitação de taxa que você pode receber ao trabalhar com APIs com limitação de taxa:

  • 403 Forbidden ou 401 Unauthorized: Algumas APIs podem começar a tratar suas solicitações como não autorizadas, negando a você o acesso ao recurso
  • 503 Service Unavailable ou 500 Internal Server Error: Se uma API estiver sobrecarregada por solicitações recebidas, ela poderá começar a enviar mensagens de erro 5XX, indicando que o servidor não está saudável. Isso geralmente é temporário e corrigido pelo provedor de serviços no devido tempo.

Como os principais provedores de API implementam os limites de taxa API

Ao definir o limite de taxa da sua API, pode ser útil dar uma olhada em como alguns dos principais provedores de API fazem isso:

  • Discord: O Discord implementa a limitação de taxa de duas maneiras: há um limite de taxa global de 50 solicitações por segundo. Além do limite global, há também limites de taxa específicos de rota que você precisa ter em mente. Você pode ler tudo sobre isso nesta documentação. Quando o limite de taxa for excedido, você receberá uma resposta HTTP 429 com um valor retry_after que pode ser usado para aguardar antes de enviar outra solicitação.
  • Twitter: O Twitter também tem limites de taxa específicos de rota que você pode encontrar na documentação deles. Quando o limite de taxa for excedido, você receberá uma resposta HTTP 429 com um valor de cabeçalho x-rate-limit-reset que informará quando você poderá retomar o acesso.
  • Reddit: A wiki arquivada da API do Reddit afirma que o limite de taxa para acessar a API do Reddit é de 60 solicitações por minuto (apenas via OAuth2). A resposta de cada chamada da API do Reddit retorna os valores dos cabeçalhos
  • X-Ratelimit-Used, X-Ratelimit-Remaining e X-Ratelimit-Reset com os quais você pode determinar quando o limite pode ser excedido e por quanto tempo.
  • Facebook: O Facebook também define limites de taxa baseados em rotas. Por exemplo, as chamadas feitas de aplicativos baseados no Facebook são limitadas a 200 * (número de usuários do aplicativo) solicitações por hora. Você pode encontrar os detalhes completos aqui. As respostas da API do Facebook conterão um cabeçalho X-App-Usage ou X-Ad-Account-Usage para ajudar você a entender quando seu uso será limitado.

Resumo

Ao criar APIs, é fundamental garantir o controle ideal do tráfego. Se você não ficar de olho no gerenciamento do tráfego, logo terá uma API sobrecarregada e não funcional. Por outro lado, ao trabalhar com uma API com taxa limitada, é importante entender como funciona a limitação de taxa e como você deve usar a API para garantir o máximo de disponibilidade e uso.

Neste guia, você aprendeu sobre limitação de taxa de API, por que ela é necessária, como pode ser implementada e algumas melhores práticas a serem consideradas ao trabalhar com limites de taxa de API.

Confira a hospedagem de aplicativos da Kinsta e crie seu próximo projeto Node.js hoje mesmo!

Você está trabalhando com uma API com limitação de taxa? Ou já implementou a limitação de taxa em sua própria API? Deixe-nos saber nos comentários abaixo!