kamoca / laravel-cep-package
Pacote para a consulta de CEPs utilizando
1.0.0
2026-05-13 20:02 UTC
Requires
- php: ^8.0
- ext-curl: *
- guzzlehttp/guzzle: ^7.9
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- illuminate/cache: ^12.58
- pestphp/pest: ^2.36
- phpoption/phpoption: ^1.9
- vlucas/phpdotenv: ^5.6
README
Pacote Laravel para consulta paralela de CEPs com fallback automático entre provedores.
Requisitos
- PHP 8.0+
- Laravel 12 ou 13
Instalação
composer require kamoca/cep
O pacote é registrado automaticamente via Laravel Package Discovery.
Configuração
Publique o arquivo de configuração:
php artisan vendor:publish --tag=cep-config
Isso cria config/cep.php. As opções disponíveis:
return [ 'timeout_ms' => env('CEP_TIMEOUT_MS', 15000), 'cache' => [ 'enabled' => env('CEP_CACHE_ENABLED', true), 'ttl' => env('CEP_CACHE_TTL', 3600), // segundos 'key' => env('CEP_CACHE_KEY', 'cep.lookup.%s'), ], 'cep_class' => \Kamoca\Cep\Transformers\CepTransformer::class, 'providers' => [ 'via_cep' => [ 'enabled' => env('FALLBACK_CEP_API_VIA_CEP_ENABLED', true), 'class' => \Kamoca\Cep\Providers\ViaCepProvider::class, ], 'brasil_api' => [ 'enabled' => env('FALLBACK_CEP_API_BRASIL_API_ENABLED', true), 'class' => \Kamoca\Cep\Providers\BrasilApiProvider::class, ], ], ];
Ou via .env:
CEP_TIMEOUT_MS=15000 CEP_CACHE_ENABLED=true CEP_CACHE_TTL=3600
Uso
Via injeção de dependência
use Kamoca\Cep\CepResolver; class EnderecoController extends Controller { public function __construct(private CepResolver $cep) {} public function show(string $cep) { $resultado = $this->cep->resolve($cep)->toArray(); return response()->json($resultado); } }
Via Facade
use Kamoca\Cep\Facade\Cep; $resultado = Cep::resolve('95914-100')->toArray();
Formato da resposta
{
"cep": "95914100",
"street": "Rua Bento Gonçalves",
"neighborhood": "Universitário",
"city": "Lajeado",
"state": "RS",
"provider": "via_cep",
"response_time_ms": 312,
"response_time_s": 0.312,
"cached": false
}
| Campo | Descrição |
|---|---|
provider |
Provedor que respondeu primeiro (via_cep ou brasil_api) |
response_time_ms |
Tempo de resposta em milissegundos |
response_time_s |
Tempo de resposta em segundos |
cached |
true quando veio do cache, false quando foi busca real |
Tratamento de erros
CEP inválido ou não encontrado lança CepResolutionException:
use Kamoca\Cep\Exceptions\CepResolutionException; try { $resultado = Cep::resolve('00000000')->toArray(); } catch (CepResolutionException $e) { // CEP não encontrado ou todos os provedores falharam return response()->json(['error' => 'CEP não encontrado'], 404); }
Personalização
Classe de CEP customizada
Para adicionar campos ou lógica própria ao objeto de retorno, implemente CepContract:
use Kamoca\Cep\Contracts\CepContract; use Kamoca\Cep\Normalizers\CepNormalize; class MeuCep implements CepContract { public function __construct( public readonly string $cep, public readonly string $cidade, public readonly string $estado, ) {} public static function fromNormalizer(CepNormalize $payload): static { return new static( cep: $payload->cep, cidade: $payload->city, estado: $payload->state, ); } public function toArray(): array { return [ 'cep' => $this->cep, 'cidade' => $this->cidade, 'estado' => $this->estado, ]; } public function jsonSerialize(): array { return $this->toArray(); } }
Registre em config/cep.php:
'cep_class' => App\Cep\MeuCep::class,
Provedor customizado
Para adicionar uma nova fonte de CEP, estenda BaseCepProvider:
use GuzzleHttp\Psr7\Request; use Kamoca\Cep\Normalizers\CepNormalize; use Kamoca\Cep\Providers\BaseCepProvider; class MinhaApiProvider extends BaseCepProvider { public function buildRequest(string $cep): Request { return new Request('GET', "https://minha-api.com/cep/{$cep}"); } protected function normalize(array $payload): CepNormalize { return new CepNormalize( cep: $payload['codigo'] ?? '', street: $payload['logradouro'] ?? '', neighborhood: $payload['bairro'] ?? '', city: $payload['municipio'] ?? '', state: $payload['uf'] ?? '', provider: $this->getName(), ); } }
Registre em config/cep.php:
'providers' => [ 'minha_api' => [ 'enabled' => true, 'class' => App\Cep\MinhaApiProvider::class, ], // provedores padrão continuam funcionando em paralelo 'via_cep' => ['enabled' => true, 'class' => \Kamoca\Cep\Providers\ViaCepProvider::class], 'brasil_api' => ['enabled' => true, 'class' => \Kamoca\Cep\Providers\BrasilApiProvider::class], ],
Todos os provedores habilitados são consultados em paralelo — o primeiro a responder com sucesso é usado.