Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Postalcode Bundle Laravel Package

christianvermeulen/postalcode-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require christianvermeulen/postalcode-bundle:dev-master
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        ChristianVermeulen\PostalcodeBundle\ChristianVermeulenPostalcodeBundle::class => ['all' => true],
    ];
    
  2. Configuration: Add your API credentials to config/packages/christian_vermeulen_postalcode.yaml:

    christian_vermeulen_postalcode:
        key: "%env(POSTCODE_API_KEY)%"
        secret: "%env(POSTCODE_API_SECRET)%"
    

    Ensure .env contains:

    POSTCODE_API_KEY=your_key_here
    POSTCODE_API_SECRET=your_secret_here
    
  3. First Use Case: Fetch address details by postal code in a controller:

    use ChristianVermeulen\PostalcodeBundle\Service\PostcodeService;
    
    public function showAddress(PostcodeService $postcodeService)
    {
        $address = $postcodeService->getAddressByPostalCode('1012AA');
        return response()->json($address);
    }
    

Implementation Patterns

Core Workflows

  1. Address Lookup: Use PostcodeService to fetch address data:

    $postcodeService->getAddressByPostalCode('1234AB');
    

    Returns structured data (e.g., street, city, latitude/longitude).

  2. Validation: Validate a postal code before processing:

    if ($postcodeService->isValidPostalCode('1234AB')) {
        // Proceed with address lookup
    }
    
  3. Reverse Geocoding: Convert coordinates to address:

    $address = $postcodeService->getAddressByCoordinates(52.3676, 4.9021);
    
  4. Integration with Forms: Use the AJAX endpoint (/postal/autocomplete) for real-time suggestions:

    fetch('/postal/autocomplete?q=1012')
        .then(response => response.json())
        .then(data => console.log(data));
    

Common Patterns

  • Dependency Injection: Inject PostcodeService into controllers/services to avoid direct instantiation.

    public function __construct(private PostcodeService $postcodeService) {}
    
  • Caching Responses: Cache API responses to reduce calls (e.g., using Symfony’s cache system):

    $cache = $this->container->get('cache.app');
    $cachedAddress = $cache->get('address_1012AA');
    if (!$cachedAddress) {
        $address = $postcodeService->getAddressByPostalCode('1012AA');
        $cache->set('address_1012AA', $address, 3600); // Cache for 1 hour
    }
    
  • Error Handling: Wrap API calls in try-catch blocks to handle rate limits or invalid responses:

    try {
        $address = $postcodeService->getAddressByPostalCode('INVALID');
    } catch (\ChristianVermeulen\PostalcodeBundle\Exception\ApiException $e) {
        $this->addFlash('error', 'Invalid postal code or API error.');
    }
    

Gotchas and Tips

Pitfalls

  1. API Key/Secret Mismanagement:

    • Hardcoding credentials in config.yml violates security best practices. Always use environment variables (.env).
    • Fix: Validate keys during bundle initialization (extend PostcodeService to throw exceptions on missing/empty keys).
  2. Rate Limiting: The free tier of api.postcode.nl has strict rate limits (e.g., 100 requests/day). Uncached repeated calls will hit limits quickly.

    • Fix: Implement a queue system (e.g., Symfony Messenger) for non-critical lookups or upgrade your plan.
  3. Postal Code Format: The API expects exact Dutch postal code formats (e.g., 1234AB, not 1234-ab or 1234).

    • Fix: Sanitize input before API calls:
      $normalizedPostcode = preg_replace('/[^0-9A-Za-z]/', '', $userInput);
      
  4. Deprecated Symfony2 Syntax: The bundle targets Symfony 2.x but may not work out-of-the-box with Symfony 5/6.

    • Fix: Override the bundle’s PostcodeService to use modern DI (e.g., autowiring) and replace AppKernel with config/bundles.php.
  5. Missing Documentation: The bundle lacks examples for advanced use cases (e.g., bulk lookups, custom field mapping).

    • Fix: Refer to the official API docs and extend the service:
      // Example: Custom method for bulk lookups
      public function getAddressesByPostalCodes(array $postalCodes): array
      {
          return array_map([$this->client, 'getAddressByPostalCode'], $postalCodes);
      }
      

Debugging Tips

  1. Enable API Debugging: Set debug: true in config to log API responses:

    christian_vermeulen_postalcode:
        key: "%env(POSTCODE_API_KEY)%"
        secret: "%env(POSTCODE_API_SECRET)%"
        debug: true  # Logs raw API responses to var/log/dev.log
    
  2. Test with Mock Data: Override PostcodeService to return mock data during development:

    // config/services.yaml
    ChristianVermeulen\PostalcodeBundle\Service\PostcodeService:
        class: App\Service\MockPostcodeService
    
  3. Handle Timeouts: The API may timeout for large payloads. Increase PHP’s timeout:

    $this->client->setOption('timeout', 30); // 30 seconds
    

Extension Points

  1. Custom Field Mapping: Extend the response model to include additional fields (e.g., municipality_code):

    // src/Entity/ExtendedAddress.php
    class ExtendedAddress extends \ChristianVermeulen\PostalcodeBundle\Entity\Address
    {
        public function setMunicipalityCode(string $code): self
        {
            $this->municipality_code = $code;
            return $this;
        }
    }
    
  2. Add Geocoding: Integrate with Google Maps or OpenStreetMap for enhanced coordinates:

    public function getEnhancedAddress(string $postalCode): array
    {
        $address = $this->getAddressByPostalCode($postalCode);
        $address['google_place_id'] = $this->geocodeService->getPlaceId(
            $address['latitude'], $address['longitude']
        );
        return $address;
    }
    
  3. Batch Processing: Process multiple postal codes asynchronously using Symfony’s Messenger:

    // src/Message/ProcessPostalCodes.php
    class ProcessPostalCodes implements MessageInterface
    {
        public function __construct(public array $postalCodes) {}
    }
    
    // src/MessageHandler/ProcessPostalCodesHandler.php
    class ProcessPostalCodesHandler
    {
        public function __invoke(ProcessPostalCodes $message, PostcodeService $service)
        {
            return array_map([$service, 'getAddressByPostalCode'], $message->postalCodes);
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui