PHPackages                             allyson/laravel-http-service - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. allyson/laravel-http-service

ActiveLibrary[HTTP &amp; Networking](/categories/http)

allyson/laravel-http-service
============================

Laravel HTTP Service with request logging and rate limiting control

v1.1.2(1w ago)173MITPHPPHP ^8.3|^8.4|^8.5

Since Dec 16Pushed 1w agoCompare

[ Source](https://github.com/allysonpdm/laravel-http-service)[ Packagist](https://packagist.org/packages/allyson/laravel-http-service)[ RSS](/packages/allyson-laravel-http-service/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (18)Versions (18)Used By (0)

HTTP Service - Laravel Package
==============================

[](#http-service---laravel-package)

Pacote Laravel para gerenciamento avançado de requisições HTTP com logging automático e controle de rate limiting.

Características
---------------

[](#características)

- **Logging automático** de todas as requisições HTTP (URL, payload, response)
- **Controle inteligente** de rate limiting (429) usando banco de dados
- **Armazenamento completo** do histórico de requisições
- **Totalmente configurável** via arquivo de config ou .env
- **Compatível** com Laravel 12
- **Gerenciamento de domínios** bloqueados com timestamps
- **Tracking de tempo** de resposta
- **Comandos Artisan** para gerenciamento
- **Controle granular** - habilite/desabilite logging e rate limit por requisição

Instalação
----------

[](#instalação)

### Via Composer

[](#via-composer)

```
composer require 3rn/http-service
```

### Configuração Inicial

[](#configuração-inicial)

Execute o comando de instalação que irá publicar config e migrations:

```
php artisan http-service:install
```

Execute as migrations:

```
php artisan migrate
```

Uso Rápido
----------

[](#uso-rápido)

```
use ThreeRN\HttpService\Facades\HttpService;

// Requisição GET
$response = HttpService::get('https://api.example.com/users');
$users = $response->json();

// Requisição POST
$response = HttpService::post('https://api.example.com/users', [
    'name' => 'John Doe',
    'email' => 'john@example.com'
]);

// Com headers customizados
$response = HttpService::post(
    'https://api.example.com/data',
    ['key' => 'value'],
    ['Authorization' => 'Bearer token123']
);
```

Métodos Disponíveis
-------------------

[](#métodos-disponíveis)

### Requisições HTTP

[](#requisições-http)

```
// GET com query parameters
HttpService::get($url, $query = [], $headers = []);

// POST com dados
HttpService::post($url, $data = [], $headers = []);

// PUT para atualização completa
HttpService::put($url, $data = [], $headers = []);

// PATCH para atualização parcial
HttpService::patch($url, $data = [], $headers = []);

// DELETE
HttpService::delete($url, $data = [], $headers = []);
```

### Controles Opcionais

[](#controles-opcionais)

```
// Desabilitar logging temporariamente
HttpService::withoutLogging()->get($url);

// Habilitar logging explicitamente
HttpService::withLogging()->post($url, $data);

// Desabilitar verificação de rate limit
HttpService::withoutRateLimit()->get($url);

// Timeout customizado (em segundos)
HttpService::timeout(60)->get($url);

// Encadear múltiplas opções
HttpService::withoutLogging()
    ->withoutRateLimit()
    ->timeout(30)
    ->get($url);
```

Cache de Requisições
--------------------

[](#cache-de-requisições)

O pacote oferece recursos avançados de cache para otimizar requisições repetidas.

### Cache com Expiração Dinâmica

[](#cache-com-expiração-dinâmica)

Cache baseado em campos da resposta que contêm informações de expiração:

```
// Cache usando campo de data/hora
// Resposta: {"token": "abc123", "expirationTime": "2025-12-17 13:02:14"}
$response = HttpService::cacheUsingExpires('expirationTime')
    ->expiresAsDatetime()  // Padrão, pode ser omitido
    ->get('https://api.example.com/auth/token');

// Cache usando campo aninhado
// Resposta: {"data": {"auth": {"expires": "2025-12-17 15:30:00"}}}
$response = HttpService::cacheUsingExpires('data.auth.expires')
    ->expiresAsDatetime()
    ->post('https://api.example.com/login', $credentials);

// Cache usando segundos
// Resposta: {"token": "xyz789", "expires_in": 3600}
$response = HttpService::cacheUsingExpires('expires_in')
    ->expiresAsSeconds()
    ->get('https://api.example.com/token');

// Cache usando minutos
// Resposta: {"session_id": "sess_123", "ttl": 30}
$response = HttpService::cacheUsingExpires('ttl')
    ->expiresAsMinutes()
    ->get('https://api.example.com/session');
```

#### Máscara de Expiração

[](#máscara-de-expiração)

Defina como interpretar o valor do campo de expiração:

- `expiresAsDatetime()` - Data/hora no formato Y-m-d H:i:s ou ISO 8601 (padrão)
- `expiresAsSeconds()` - Valor em segundos
- `expiresAsMinutes()` - Valor em minutos

#### TTL de Fallback

[](#ttl-de-fallback)

Use um TTL padrão caso o campo não seja encontrado:

```
// Se 'expirationTime' não existir, cacheia por 2 horas (7200 segundos)
$response = HttpService::cacheUsingExpires('expirationTime', 7200)
    ->expiresAsDatetime()
    ->get('https://api.example.com/data');
```

### Cache Fixo

[](#cache-fixo)

Cache com tempo de vida fixo:

```
// Cache por 1 hora (3600 segundos)
$response = HttpService::withCache(3600)
    ->get('https://api.example.com/data');
```

### Cache Condicional

[](#cache-condicional)

Cache ativado apenas após múltiplas chamadas:

```
// Cache após 3 chamadas em 60 segundos, com TTL de 1 hora
$response = HttpService::cacheWhen(3, 60, 3600)
    ->get('https://api.example.com/data');
```

### Desabilitar Cache

[](#desabilitar-cache)

```
// Desabilitar cache para uma requisição específica
$response = HttpService::withoutCache()
    ->get('https://api.example.com/data');
```

### Limpar Cache

[](#limpar-cache)

```
// Limpar todo o cache de requisições
HttpService::clearCache();
```

### Cache por Status (cacheOnly / cacheExcept)

[](#cache-por-status-cacheonly--cacheexcept)

Você pode controlar o cache com base nos códigos HTTP da resposta usando os métodos `cacheOnly` e `cacheExcept`.

- **`cacheOnly(array $statuses, ?int $ttl = null): self`**
    - Armazena em cache **apenas** as respostas cujo `status_code` esteja presente em `$statuses`.
    - Se `$ttl` for passado, ele sobrescreve o TTL para essa requisição específica (em segundos).
    - Retorna uma cópia (`clone`) do `HttpService`, então a configuração afeta apenas a cadeia encadeada desta chamada.

```
// Cachear SOMENTE respostas 200 por 10 minutos
$response = HttpService::cacheOnly([200], 600)
        ->get('https://api.example.com/data');

// Cachear respostas 200 e 201 (com TTL customizado)
$response = HttpService::cacheOnly([200, 201], 300)
        ->post('https://api.example.com/create', $payload);
```

- **`cacheExcept(array $statuses, ?int $ttl = null): self`**
    - Armazena em cache **todas** as respostas exceto aquelas cujo `status_code` esteja em `$statuses`.
    - Se `$ttl` for passado, ele sobrescreve o TTL para essa requisição específica (em segundos).
    - Retorna uma cópia (`clone`) do `HttpService`, então a configuração afeta apenas a cadeia encadeada desta chamada.

```
// Cachear tudo exceto erro 500
$response = HttpService::cacheExcept([500])
        ->get('https://api.example.com/data');

// Cachear tudo exceto 4xx e 5xx (exemplo)
$response = HttpService::cacheExcept([400,401,403,404,500,502,503], 3600)
        ->get('https://api.example.com/data');
```

Observações de implementação:

- Os métodos `cacheOnly` e `cacheExcept` definem `cacheStrategy = 'always'`, portanto ativam o cache para aquela chamada.
- Os filtros são aplicados somente no momento de armazenamento: o pacote verifica o `status` da resposta e respeita `cacheOnlyStatuses` e `cacheExceptStatuses` antes de persistir no cache.
- `cacheOnly` limpa `cacheExceptStatuses` e vice-versa; assim, elas não entram em conflito.
- Se você preferir limpar ambos os filtros manualmente, use `clearCacheStatusFilters()`.

Revisão da implementação

Após revisar `src/Services/HttpService.php`, os métodos `cacheOnly` e `cacheExcept` já estão implementados corretamente e não precisam de alterações funcionais imediatas. Uma sugestão opcional para consistência é que `clearCacheStatusFilters()` poderia retornar um `clone` (como outros métodos que configuram comportamento) para manter o padrão imutável/encadeável, mas isso não é obrigatório.

### Formatos de Data/Hora Suportados

[](#formatos-de-datahora-suportados)

Para `expiresAsDatetime()`:

- `Y-m-d H:i:s` - Exemplo: "2025-12-17 13:02:14"
- ISO 8601 - Exemplo: "2025-12-17T13:02:14Z"
- Qualquer formato aceito pelo construtor DateTime do PHP

### Notação de Ponto para Campos Aninhados

[](#notação-de-ponto-para-campos-aninhados)

- `'field'` → busca `$response['field']`
- `'data.auth.expires'` → busca `$response['data']['auth']['expires']`
- `'user.preferences.cache.ttl'` → busca `$response['user']['preferences']['cache']['ttl']`

### Exemplos Completos

[](#exemplos-completos)

Veja [examples/cache-expires-examples.php](examples/cache-expires-examples.php) para mais exemplos de uso.

Rate Limiting
-------------

[](#rate-limiting)

O pacote gerencia automaticamente erros 429 (Too Many Requests):

### Funcionamento Automático

[](#funcionamento-automático)

1. **Antes da requisição**: Verifica se o domínio está bloqueado
2. **Durante a requisição**: Executa normalmente se não houver bloqueio
3. **Após 429**: Bloqueia o domínio automaticamente
4. **Retry-After**: Respeita o header `Retry-After` do servidor

### Tratamento de Exceções

[](#tratamento-de-exceções)

```
use ThreeRN\HttpService\Exceptions\RateLimitException;

try {
    $response = HttpService::get('https://api.example.com/data');
} catch (RateLimitException $e) {
    echo "Domínio bloqueado: " . $e->getDomain();
    echo "Aguarde: " . $e->getRemainingMinutes() . " minutos";
}
```

### Estratégia Wait-on-Rate-Limit

[](#estratégia-wait-on-rate-limit)

Ao invés de lançar `RateLimitException`, o serviço pode **aguardar de forma síncrona** até o bloqueio expirar e então executar a requisição normalmente.

**Ativar globalmente** via config ou `.env`:

```
HTTP_SERVICE_RATE_LIMIT_WAIT_ON_BLOCK=true
```

**Ativar por chamada** com `waitOnRateLimit()`:

```
// Aguarda o bloqueio expirar e então executa
$response = HttpService::waitOnRateLimit()->get('https://api.example.com/data');
```

**Desativar pontualmente** (quando estiver ligado globalmente):

```
// Lança RateLimitException normalmente, ignorando a config global
$response = HttpService::throwOnRateLimit()->get('https://api.example.com/data');
```

> **Atenção:** O processo ficará bloqueado (via `sleep`) pelo tempo exato restante do bloqueio. Não use em requests web síncronos com bloqueios longos. Ideal para jobs/queues ou cenários onde o `default_block_time` é pequeno.

### Gerenciamento Manual

[](#gerenciamento-manual)

```
use ThreeRN\HttpService\Models\RateLimitControl;

// Verificar se está bloqueado
$isBlocked = RateLimitControl::isBlocked('api.example.com');

// Tempo restante de bloqueio (em minutos)
$minutes = RateLimitControl::getRemainingBlockTime('api.example.com');

// Tempo restante de bloqueio (em segundos)
$seconds = RateLimitControl::getRemainingBlockSeconds('api.example.com');

// Bloquear manualmente por 30 minutos
RateLimitControl::blockDomain('api.example.com', 30);

// Bloquear com motivo registrado
RateLimitControl::blockDomain('api.example.com', 30);
// (defina 'reason' via create/update direto no model se necessário)

// Desbloquear manualmente
RateLimitControl::unblockDomain('api.example.com');

// Listar bloqueios ativos
$blocks = RateLimitControl::active()->get();

// Limpar bloqueios expirados
$count = RateLimitControl::cleanExpiredBlocks();
```

Circuit Breaker
---------------

[](#circuit-breaker)

O circuit breaker é um padrão de resiliência que **abre o circuito** após N falhas consecutivas de um domínio, bloqueando requisições imediatamente (sem nem tentar a conexão) durante um período de recuperação. Diferente do rate limiting (que reage a 429), o circuit breaker é genérico e protege contra qualquer tipo de falha (5xx, timeouts, erros de conexão).

### Estados

[](#estados)

EstadoComportamento**CLOSED**Operação normal. Falhas são contadas.**OPEN**Circuito aberto. Lança `CircuitBreakerException` imediatamente.**HALF-OPEN**Após o `recovery_time`, permite uma requisição de sondagem. Se sucesso → CLOSED. Se falha → OPEN.### Habilitando Globalmente

[](#habilitando-globalmente)

Via config ou `.env`:

```
HTTP_SERVICE_CIRCUIT_BREAKER_ENABLED=true
HTTP_SERVICE_CIRCUIT_BREAKER_THRESHOLD=5
HTTP_SERVICE_CIRCUIT_BREAKER_RECOVERY_TIME=60
```

### Exemplo: configurando tempos (circuit breaker)

[](#exemplo-configurando-tempos-circuit-breaker)

O `HTTP_SERVICE_CIRCUIT_BREAKER_RECOVERY_TIME` é expresso em **segundos**. Exemplo: aumentar para 120 segundos (2 minutos):

```
# Tempo de recuperação do circuit breaker em segundos
HTTP_SERVICE_CIRCUIT_BREAKER_RECOVERY_TIME=120

# Opcional: aguardar automaticamente até o tempo de recuperação antes de tentar (wait-on-circuit-breaker)
HTTP_SERVICE_CIRCUIT_BREAKER_WAIT_ON_OPEN=true
```

Observação: diferentemente do rate limit, que usa minutos para o bloqueio padrão (`default_block_time`), o circuit breaker usa segundos para `recovery_time`.

### Habilitando por Chamada

[](#habilitando-por-chamada)

```
// Parâmetros: threshold de falhas, tempo de recuperação em segundos, statuses de falha
$response = HttpService::withCircuitBreaker(5, 60)
    ->get('https://api.example.com/data');

// Customizando statuses que contam como falha (padrão: 500-599)
$response = HttpService::withCircuitBreaker(3, 30, [500, 502, 503, 504])
    ->post('https://api.example.com/data', $payload);

// Desabilitando pontualmente (quando habilitado globalmente)
$response = HttpService::withoutCircuitBreaker()
    ->get('https://api.example.com/health');
```

### Tratamento de Exceções

[](#tratamento-de-exceções-1)

```
use ThreeRN\HttpService\Exceptions\CircuitBreakerException;

try {
    $response = HttpService::withCircuitBreaker()->get('https://api.example.com/data');
} catch (CircuitBreakerException $e) {
    echo "Circuito aberto para: " . $e->getDomain();
    echo "Tente novamente em: " . $e->getRemainingSeconds() . " segundos";
}
```

### Wait on Circuit Breaker

[](#wait-on-circuit-breaker)

Por padrão, quando o circuito está OPEN o serviço lança `CircuitBreakerException` imediatamente. Com `waitOnCircuitBreaker()` o comportamento muda: o serviço **aguarda (`sleep`) até o tempo de recuperação expirar** e então tenta a requisição novamente em estado HALF-OPEN — idêntico ao `waitOnRateLimit()` para o rate limiting.

> **Atenção:** não use em processos web síncronos com `recovery_time` longo. Ideal para jobs/queues ou quando o `circuit_breaker_recovery_time` for baixo.

```
// Ativa por chamada — aguarda o circuito recuperar e re-tenta
$response = HttpService::withCircuitBreaker(3, 10)
    ->waitOnCircuitBreaker()
    ->get('https://api.example.com/data');

// Desativa pontualmente (quando a config global estiver habilitada)
$response = HttpService::throwOnCircuitBreaker()
    ->get('https://api.example.com/data');
```

**Ativando globalmente** via config ou `.env`:

```
HTTP_SERVICE_CIRCUIT_BREAKER_WAIT_ON_OPEN=true
```

O método `throwOnCircuitBreaker()` permite sobrescrever o comportamento global em chamadas específicas.

### Diferença entre Circuit Breaker e Rate Limiting

[](#diferença-entre-circuit-breaker-e-rate-limiting)

Rate LimitingCircuit Breaker**Aberto por**Resposta 429 (Too Many Requests)N falhas consecutivas (5xx, timeout, etc.)**Protege contra**Exceder cota da APIServiço degradado/fora do ar**Tempo de bloqueio**Respeitando Retry-After do servidorConfigurável (`recovery_time`)**Persistência**Banco de dadosCache do Laravel**Sondagem automática**NãoSim (HALF-OPEN)### Namespace Compartilhado entre Projetos

[](#namespace-compartilhado-entre-projetos)

Por padrão, o estado do circuit breaker é **isolado por aplicação** — cada projeto mantém sua própria contagem de falhas. Isso é o comportamento correto na maioria dos casos.

Se dois ou mais projetos usam o **mesmo driver de cache** (ex: mesmo Redis) e precisam compartilhar o estado — para que o App B saiba que o App A já detectou que um domínio está fora do ar — configure o mesmo namespace nos dois:

```
# App A e App B — mesmo Redis, mesmo namespace
HTTP_SERVICE_CB_NAMESPACE=produtivo
```

Com isso, as chaves de cache ficam no formato `http_cb_produtivo_` e são compartilhadas entre os projetos.

Se `HTTP_SERVICE_CB_NAMESPACE` não for definido (padrão), cada app tem seu estado independente com chaves `http_cb_`.

> **Atenção:** ao compartilhar namespace, um único projeto sofrendo falhas de rede ou erros locais pode abrir o circuito para todos os outros. Use com cuidado em ambientes heterogêneos.

Consultar Logs
--------------

[](#consultar-logs)

### Models e Query Scopes

[](#models-e-query-scopes)

```
use ThreeRN\HttpService\Models\HttpRequestLog;

// Buscar por URL
$logs = HttpRequestLog::byUrl('api.example.com')->get();

// Buscar por método HTTP
$posts = HttpRequestLog::byMethod('POST')->get();

// Buscar por status code
$errors = HttpRequestLog::byStatusCode(500)->get();

// Requisições com erro
$withErrors = HttpRequestLog::withErrors()->get();

// Requisições bem-sucedidas (2xx)
$successful = HttpRequestLog::successful()->get();

// Últimas 24 horas
$recent = HttpRequestLog::where('created_at', '>=', now()->subDay())
    ->orderBy('created_at', 'desc')
    ->get();

// Requisições lentas (mais de 5 segundos)
$slow = HttpRequestLog::where('response_time', '>', 5)->get();
```

### Estrutura do Log

[](#estrutura-do-log)

Cada log contém:

- `url` - URL completa da requisição
- `method` - Método HTTP (GET, POST, etc)
- `payload` - Dados enviados (JSON)
- `response` - Resposta recebida (JSON)
- `status_code` - Código de status HTTP
- `response_time` - Tempo de resposta em segundos
- `error_message` - Mensagem de erro (se houver)
- `created_at` / `updated_at` - Timestamps

### Estrutura do Controle de Rate Limit

[](#estrutura-do-controle-de-rate-limit)

Cada registro de bloqueio contém:

- `domain` - Domínio bloqueado
- `blocked_at` - Momento do bloqueio
- `wait_time_minutes` - Duração do bloqueio em minutos
- `unblock_at` - Momento em que o bloqueio expira
- `reason` - Motivo do bloqueio (opcional, preenchível via `create`/`update`)
- `created_at` / `updated_at` - Timestamps

Comandos Artisan
----------------

[](#comandos-artisan)

### Instalação

[](#instalação-1)

```
# Publicar config e migrations
php artisan http-service:install
```

### Gerenciamento de Bloqueios

[](#gerenciamento-de-bloqueios)

```
# Listar domínios bloqueados
php artisan http-service:list-blocks

# Desbloquear domínio específico
php artisan http-service:unblock api.example.com

# Limpar bloqueios expirados
php artisan http-service:clean-blocks
```

### Limpeza de Logs

[](#limpeza-de-logs)

```
# Limpar logs antigos (usa log_retention_days do config)
php artisan http-service:clean-logs

# Limpar logs com período customizado
php artisan http-service:clean-logs --days=7
```

Configuração
------------

[](#configuração)

Arquivo `config/http-service.php`:

```
return [
    // Habilitar logging de requisições
    'logging_enabled' => env('HTTP_SERVICE_LOGGING_ENABLED', true),

    // Habilitar controle de rate limiting
    'rate_limit_enabled' => env('HTTP_SERVICE_RATE_LIMIT_ENABLED', true),

    // Tempo de bloqueio padrão após 429 (minutos)
    'default_block_time' => env('HTTP_SERVICE_DEFAULT_BLOCK_TIME', 15),

    // Aguardar o bloqueio expirar em vez de lançar exceção (wait-on-rate-limit)
    'rate_limit_wait_on_block' => env('HTTP_SERVICE_RATE_LIMIT_WAIT_ON_BLOCK', false),

    // Timeout padrão de requisições (segundos)
    'timeout' => env('HTTP_SERVICE_TIMEOUT', 30),

    // Limpeza automática de bloqueios expirados
    'auto_clean_expired_blocks' => env('HTTP_SERVICE_AUTO_CLEAN_EXPIRED', true),

    // Retenção de logs (dias) - null para manter indefinidamente
    'log_retention_days' => env('HTTP_SERVICE_LOG_RETENTION_DAYS', 30),

    // Conexão de banco para gravação de logs (null = conexão padrão)
    'logging_connection' => env('HTTP_SERVICE_LOGGING_CONNECTION', null),

    // Conexão de banco para rate limiting (null = usa logging_connection ou padrão)
    'ratelimit_connection' => env('HTTP_SERVICE_RATELIMIT_CONNECTION', null),

    // Nome customizado da tabela de logs (null = 'http_request_logs')
    'logging_table' => env('HTTP_SERVICE_LOGGING_TABLE', null),

    // Nome customizado da tabela de rate limit (null = 'rate_limit_controls')
    'ratelimit_table' => env('HTTP_SERVICE_RATELIMIT_TABLE', null),

    // Circuit Breaker
    'circuit_breaker_enabled'         => env('HTTP_SERVICE_CIRCUIT_BREAKER_ENABLED', false),
    'circuit_breaker_threshold'       => env('HTTP_SERVICE_CIRCUIT_BREAKER_THRESHOLD', 5),
    'circuit_breaker_recovery_time'   => env('HTTP_SERVICE_CIRCUIT_BREAKER_RECOVERY_TIME', 60),
    'circuit_breaker_failure_statuses'=> range(500, 599), // não configurável via env
    'circuit_breaker_namespace'       => env('HTTP_SERVICE_CB_NAMESPACE', null),

    // Aguardar recuperação do circuito em vez de lançar exceção (wait-on-circuit-breaker)
    'circuit_breaker_wait_on_open'    => env('HTTP_SERVICE_CIRCUIT_BREAKER_WAIT_ON_OPEN', false),
];
```

### Variáveis de Ambiente (.env)

[](#variáveis-de-ambiente-env)

```
HTTP_SERVICE_LOGGING_ENABLED=true
HTTP_SERVICE_RATE_LIMIT_ENABLED=true
HTTP_SERVICE_DEFAULT_BLOCK_TIME=15
HTTP_SERVICE_RATE_LIMIT_WAIT_ON_BLOCK=false
HTTP_SERVICE_TIMEOUT=30
HTTP_SERVICE_AUTO_CLEAN_EXPIRED=true
HTTP_SERVICE_LOG_RETENTION_DAYS=30
HTTP_SERVICE_LOGGING_CONNECTION=
HTTP_SERVICE_RATELIMIT_CONNECTION=
HTTP_SERVICE_LOGGING_TABLE=
HTTP_SERVICE_RATELIMIT_TABLE=
HTTP_SERVICE_CIRCUIT_BREAKER_ENABLED=false
HTTP_SERVICE_CIRCUIT_BREAKER_THRESHOLD=5
HTTP_SERVICE_CIRCUIT_BREAKER_RECOVERY_TIME=60
HTTP_SERVICE_CIRCUIT_BREAKER_WAIT_ON_OPEN=false
HTTP_SERVICE_CB_NAMESPACE=
```

### Tabelas Customizáveis

[](#tabelas-customizáveis)

Por padrão o pacote usa `http_request_logs` e `rate_limit_controls`. Para usar nomes diferentes sem alterar as migrations:

```
HTTP_SERVICE_LOGGING_TABLE=minha_tabela_de_logs
HTTP_SERVICE_RATELIMIT_TABLE=meu_controle_de_ratelimit
```

Os models `HttpRequestLog` e `RateLimitControl` aplicam o nome configurado via `setTable()` no construtor.

### Conexões de Banco Separadas

[](#conexões-de-banco-separadas)

Para isolar logs e rate limiting da conexão principal (útil para garantir persistência mesmo com rollback de transação):

```
HTTP_SERVICE_LOGGING_CONNECTION=logging
HTTP_SERVICE_RATELIMIT_CONNECTION=logging
```

Se `HTTP_SERVICE_RATELIMIT_CONNECTION` não estiver definido, o pacote usa `HTTP_SERVICE_LOGGING_CONNECTION` como fallback. Se nenhum estiver definido, usa a conexão padrão do Laravel.

Exemplos de Uso
---------------

[](#exemplos-de-uso)

### Em Controllers

[](#em-controllers)

```
namespace App\Http\Controllers;

use ThreeRN\HttpService\Facades\HttpService;
use ThreeRN\HttpService\Exceptions\RateLimitException;

class ApiController extends Controller
{
    public function fetchData()
    {
        try {
            $response = HttpService::get('https://api.example.com/data');

            return response()->json([
                'success' => true,
                'data' => $response->json(),
            ]);
        } catch (RateLimitException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Rate limited',
                'retry_in_minutes' => $e->getRemainingMinutes(),
            ], 429);
        }
    }
}
```

### Em Jobs/Queue

[](#em-jobsqueue)

```
namespace App\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use ThreeRN\HttpService\Facades\HttpService;
use ThreeRN\HttpService\Exceptions\RateLimitException;

class ProcessApiDataJob implements ShouldQueue
{
    public function handle()
    {
        try {
            $response = HttpService::post('https://api.example.com/process', $this->data);
            // Processar resposta...
        } catch (RateLimitException $e) {
            // Reagendar job para quando o bloqueio expirar
            $this->release($e->getRemainingMinutes() * 60);
        }
    }
}
```

### Com Retry Logic

[](#com-retry-logic)

```
function makeApiRequestWithRetry($url, $data, $maxRetries = 3)
{
    $attempt = 0;

    while ($attempt < $maxRetries) {
        try {
            $response = HttpService::timeout(30)->post($url, $data);

            if ($response->successful()) {
                return $response->json();
            }

        } catch (RateLimitException $e) {
            $waitMinutes = $e->getRemainingMinutes();
            sleep($waitMinutes * 60);
        } catch (\Exception $e) {
            sleep(5); // Aguarda antes de tentar novamente
        }

        $attempt++;
    }

    throw new \Exception("Falha após {$maxRetries} tentativas");
}
```

Manutenção e Performance
------------------------

[](#manutenção-e-performance)

### Limpeza Automática

[](#limpeza-automática)

Configure tarefas agendadas no `app/Console/Kernel.php`:

```
protected function schedule(Schedule $schedule)
{
    // Limpar bloqueios expirados diariamente
    $schedule->command('http-service:clean-blocks')->daily();

    // Limpar logs antigos semanalmente
    $schedule->command('http-service:clean-logs')->weekly();
}
```

### Índices de Banco de Dados

[](#índices-de-banco-de-dados)

As migrations já incluem índices otimizados para:

- Consultas por URL
- Consultas por método HTTP
- Consultas por status code
- Consultas por data
- Verificação de bloqueios de domínio

Requisitos
----------

[](#requisitos)

- PHP 8.2 ou superior
- Laravel 12.x
- Banco de dados (MySQL, PostgreSQL, SQLite, etc)

Estrutura do Pacote
-------------------

[](#estrutura-do-pacote)

```
http-service/
├── config/
│   └── http-service.php
├── database/
│   └── migrations/
├── src/
│   ├── Console/
│   │   └── Commands/
│   ├── Exceptions/
│   ├── Facades/
│   ├── Models/
│   ├── Services/
│   └── HttpServiceProvider.php
├── examples/
└── README.md

```

Documentação Adicional
----------------------

[](#documentação-adicional)

- [Guia de Instalação Detalhado](INSTALLATION.md)
- [Exemplos de Uso](examples/usage-examples.php)
- [Changelog](CHANGELOG.md)

Contribuindo
------------

[](#contribuindo)

Contribuições são bem-vindas! Por favor, abra uma issue ou pull request.

Licença
-------

[](#licença)

MIT License - veja [LICENSE](LICENSE) para detalhes.

Suporte
-------

[](#suporte)

Para dúvidas ou problemas:

- Abra uma issue no GitHub
- Email:

Créditos
--------

[](#créditos)

Desenvolvido por Allyson P. da Mata

###  Health Score

48

—

FairBetter than 93% of packages

Maintenance98

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~12 days

Recently: every ~32 days

Total

17

Last Release

7d ago

PHP version history (2 changes)v1.0.0PHP ^8.2

v1.1.0PHP ^8.3|^8.4|^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/27ef618d6449b3209374d96ef45e55f079e3c80453d39620c5ac338d27442bc0?d=identicon)[allysonpdm](/maintainers/allysonpdm)

---

Top Contributors

[![allysonpdm](https://avatars.githubusercontent.com/u/4742011?v=4)](https://github.com/allysonpdm "allysonpdm (25 commits)")

---

Tags

httplaravelloggingrate limiting

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/allyson-laravel-http-service/health.svg)

```
[![Health](https://phpackages.com/badges/allyson-laravel-http-service/health.svg)](https://phpackages.com/packages/allyson-laravel-http-service)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M8.5k](/packages/larastan-larastan)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.6k30.0M148](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k15.1M132](/packages/laravel-pulse)[mike-bronner/laravel-model-caching

Automatic caching for Eloquent models.

2.4k91.9k1](/packages/mike-bronner-laravel-model-caching)[api-platform/laravel

API Platform support for Laravel

58171.8k14](/packages/api-platform-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
