Weave 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

Simple Address Laravel Package

fndmiranda/simple-address

Laravel package for Brazilian addresses: ships migrations, models and seeders for states and cities, plus a CEP (zip code) lookup service that fills address data automatically. Simple to install and easy to integrate into any Eloquent application.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package:

    composer require fndmiranda/simple-address
    
  2. Publish config and migrations:

    php artisan vendor:publish --provider="Fndmiranda\SimpleAddress\SimpleAddressServiceProvider"
    php artisan migrate
    

    If the provider is not auto-listed, run php artisan vendor:publish and select the simple-address config/migration tags.

  3. Review config/simple-address.php immediately. Set the default postcode driver, any API keys, geocoder driver, table names, and model overrides before building on top of it.

  4. Add the package’s address trait to the model that owns addresses, usually User or Company:

    use Fndmiranda\SimpleAddress\Traits\Addressable; // confirm exact trait name in README
    
    class User extends Authenticatable
    {
        use Addressable;
    }
    
  5. First use case: a profile address form with postcode autofill. When the user enters a CEP/postcode, call your endpoint, use the package’s postcode lookup to hydrate street/district/city/state, then save the address through the model relationship.

Look first at:

  • README usage examples
  • config/simple-address.php
  • package migrations
  • src/Models
  • src/Services or postcode/gecoder driver classes

Implementation Patterns

Polymorphic address ownership Use the package trait on every entity that can own an address. This keeps addresses reusable across users, companies, orders, and stores:

$user->addresses()->create($validated);
$company->addresses()->create($validated);

Postcode lookup as an application service Wrap the package lookup in your own action so validation, normalization, caching, and fallback logic stay in one place:

class ResolvePostcode
{
    public function __construct(private Postcode $postcode) {}

    public function handle(string $postcode): array
    {
        $postcode = preg_replace('/\D/', '', $postcode);

        return Cache::remember(
            "postcode:{$postcode}",
            now()->addDay(),
            fn () => $this->postcode->search($postcode)->toArray()
        );
    }
}

Create or update addresses without losing user input Treat postcode API data as defaults, not authoritative overrides. Users often correct number, complement, and district:

$lookup = $resolver->handle($data['postcode']);

$address = $user->addresses()->updateOrCreate(
    ['postcode' => $data['postcode'], 'is_default' => true],
    array_merge($lookup, array_filter($data))
);

Geocode asynchronously Geocoding is slow and can fail independently of address creation. Dispatch a job after save:

static::saved(function (Address $address) {
    if ($address->wasChanged(['postcode', 'street', 'number', 'city_id'])) {
        GeocodeAddress::dispatch($address)->onQueue('geocoding');
    }
});

Store latitude/longitude only when the geocoder returns a confident result.

Use a frontend endpoint for postcode autofill Create a small JSON endpoint or Livewire action for the postcode field. Debounce requests, show loading state, and let the user keep typing. Do not block form submission on a third-party API unless the address is required for checkout.

Fallback across postcode providers If the package supports multiple drivers, configure a primary and fallback. If not, implement a small wrapper that tries providers in order and caches the successful result. Keep provider-specific response mapping out of controllers.

Custom driver extension Implement the package’s driver contract and register it in config/simple-address.php when you need another postcode or geocoding provider. This is the cleanest extension point; avoid editing vendor files.

Eager load address relationships Address listings often need city/state/country data:

User::with('addresses.city.state.country')->paginate();

Without eager loading, address tables page will generate N+1 queries.

Testing Fake external HTTP calls with Http::fake() and assert your action maps provider responses into address fields. Keep one test per driver plus one fallback test.

Gotchas and Tips

  • Small package, limited surface area. With ~76 stars, read the source for the exact trait, service, and driver names before assuming README accuracy. Pin a version and add your own integration tests around postcode lookup and geocoding.
  • External APIs are unreliable. Set HTTP timeouts, retries, and a fallback provider. Never let postcode lookup failure block unrelated form saves.
  • Normalize postcodes. Strip spaces, hyphens, and punctuation before lookup, but preserve the user’s original formatting if needed for display. Brazil CEPs and other postcode formats differ; use a country-aware driver.
  • Geocoding costs money and misses addresses. Keep API keys in .env, queue geocoding, and handle “no result” without failing the address save.
  • Publish migrations before migrating. Check for conflicts with existing addresses, cities, states, or countries tables. If migrating an existing app, map old address columns deliberately.
  • Watch city/state duplication. Postcode APIs often return city/state names. Use firstOrCreate with unique constraints or you will accumulate duplicate cities.
  • Morph maps matter. If you use Relation::enforceMorphMap(), register the addressable models consistently or polymorphic address lookups will break.
  • Do not blindly overwrite user-entered fields. Merge API lookup data only into empty fields such as street/district/city; leave number and complement under user control.
  • Add your own validation and authorization. The package manages address data, not policies. Validate postcode format, number, country, and ownership before creating addresses.
  • Beware config cache. After changing config/simple-address.php, run php artisan config:clear in local development.
  • Localization is not automatic. Provider responses may be Portuguese-labelled or country-specific. Normalize labels before exposing them in multilingual UIs.
  • It is not a geospatial search engine. Storing latitude/longitude is useful, but radius search, distance sorting, and map clustering require additional query logic.
  • Use model observers carefully. Address observers can fire during imports and seeders. Guard geocoding jobs with $address->exists and avoid dispatching in test factories unless explicitly needed.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package