liquetsoft/fias-laravel
Laravel package for integrating Russia’s FIAS address database. Provides Eloquent models, migrations, and Artisan commands to import and update address data, making it easier to add hierarchical address lookup and maintenance to Laravel applications.
This is a thin Laravel wrapper around liquetsoft/fias (the actual importer/parser lives there). Treat the wrapper as glue: service provider, config, migrations, and a Fias facade over the core manager. Before wiring anything, skim config/fias.php and the core package's README — most behavior you'll care about (download protocol, entities, batch sizing, parsers) is defined there, not here.
Minimum path to a working install:
composer require liquetsoft/fias-laravelphp artisan vendor:publish --provider="Liquetsoft\Fias\Laravel\FiasServiceProvider". In most setups you'll instead run the package's install command (check php artisan list fias) which publishes and executes the schema in one step.config/fias.php and use it. MySQL/sqlite will technically work for tiny test fixtures but fall over on the full GAR dataset (well over 100M rows across the entity tables, tens of GB on disk).delta first.use Liquetsoft\Fias\Laravel\Facade\Fias;
Fias::findAddressObjectByAddress('г Москва, ул Тверская, д 1');
Fias::findHouseByAddress('г Москва, ул Тверская, д 1');
Fias::findAddressObjectByGuid($guid);
For a first "aha" use case, build a small autocomplete endpoint that calls findAddressObjectByAddress plus the corresponding house/room lookup, and return a normalized {guid, display, kind} payload.
Treat FIAS GUIDs as the canonical join key. Every address in your domain (user addresses, orders, shops, delivery zones) should reference the address_object, house, apartment, or room GUID — never a FIAS row ID. Imports rewrite rows; GUIDs don't change. That single rule saves you from the most common re-import pain.
Separate database connection. Don't stuff ~150M rows into your application's primary DB. Define a fias connection in config/database.php, point the FIAS config at it, and keep your app DB free of the bulk. Cross-DB joins then become a caching problem rather than a SQL problem.
Wrapping it as a service. Don't scatter Fias:: calls through controllers. Wrap the facade in a FiasAddressRepository (or similar) with methods like resolveAddress(string $raw): ?ResolvedAddress and expandHouse(string $guid): ?HouseData. This is where you'll layer normalization (case folding, ё→е, stripping г., ул., д.) because FIAS lookups are literal.
Scheduled nightly updates. The GAR/FIAS update endpoint ships incremental deltas. Wire the package's update command into app/Console/Kernel.php (or a scheduled Schedule::command('fias:update')->daily()), and run it before the import — it handles delta ordering internally via its version table. Give the scheduler withoutOverlapping() and a generous timeout.
Custom entities / extension. If your region or use case needs extra fields on houses or address objects, extend the base entity classes and register them in config/fias.php. The core package will hydrate them during import just like the built-in ones. This is cleaner than post-processing rows into a side table.
Test fixtures, not test imports. For CI, commit a tiny handcrafted XML/JSON fixture and point the parser at it. Never let tests hit the live endpoint. The Fias facade is a good seam to fake in feature tests.
Layering with caching. findAddressObjectByAddress on a cold PostgreSQL is fine; repeated calls from a user typing an address are not. Cache by normalized address string (short TTL) and by GUID (long TTL, invalidated by import version). The package does not do this for you.
Multi-region imports. If you only operate in a few regions, filter the import by region code at the download stage. It cuts import from a night to minutes and keeps the tables small enough that naive LIKE queries stay viable.
tsvector, or similar). Don't assume portability. If you must use MySQL, expect to fork the migrations and lose some performance.path) needs headroom for both the zipped and unzipped payload. Point it at a fast local disk, not NFS.max_execution_time and PHP memory limits. If you trigger from a controller, dispatch a long-running job and poll status via the package's check command or your own progress table.pg_stat_activity while the import runs.STEAD, CAR_ENTRANCE, etc.). Pin your liquetsoft/fias version and verify which format your import expects — mixing parsers and data sources is a silent-corruption trap.fias.nalog.ru is finicky. It rate-limits, occasionally 502s, and requires accepting the usage terms (the client sends a version header). Wrap the download in retries with backpressure; the package's downloader has hooks but you may need to subclass.NORMATIVE_DOCS and reorganized municipalities). Never treat FIAS as append-only; run a reconciliation job after each delta if you keep denormalized copies.FiasManager from the container — it is not a static registry of data. If you want a "current import version" helper, add it to a wrapper rather than calling into internals.config/fias.php, the parser/storage implementations (swap in a custom StorageInterface if you must write to a different backend), and the import pipeline listeners for post-import hooks (e.g., reindexing, cache flush).artisan list is more accurate than the README. Wrapper command names have churned across versions; run php artisan list fias after install rather than copy-pasting from docs.liquetsoft/fias, whose API is stable; this package is a small adapter. Read that repo's changelog when bumping — 99% of behavior changes will surface there, not in the Laravel wrapper's release notes.How can I help you explore Laravel packages today?