liberusoftware/import-export-api
Laravel package that adds import and export API endpoints to your application, making it easy to move data in and out through structured, secure REST routes for bulk transfers.
This is a presentation-adapter module: it is the HTTP/API skin over an underlying import/export domain service. Treat it as a thin delivery layer, not as the place where import logic lives. The repository has no published documentation, zero stars, and an unasserted license, so budget time to read the source before wiring it into anything important.
Install and discover
composer require liberusoftware/import-export-api
Because it is a Liberu module, expect package auto-discovery via a service provider. Confirm with:
php artisan about
php artisan route:list | grep -i import
If routes do not appear, the provider may not be registered for your Laravel version, or it may expect a parent modular application (e.g. a modules/ structure) rather than a vanilla app. Check composer.json for extra.laravel.providers and the required framework constraints before assuming compatibility.
Where to look first, in this order
routes/ (or src/Routes/) — the actual API surface and middleware applied.src/Http/Controllers — the endpoints and what service/action each one delegates to.src/Http/Requests and src/Http/Resources — validation rules and response shapes.config/ — the publishable config file (disk, queue, chunk size, route prefix, middleware).src/Adapters / src/Services — the seam to the underlying import/export implementation.composer.json — required sibling packages (likely a core import-export module), PHP and Laravel constraints, and the license field.First use case
The realistic day-one flow is: authenticate, upload a file, let the server queue the import, then poll for status. Start with a single curl against the route you found in route:list:
curl -X POST https://app.test/api/imports \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
-F "[email protected]" \
-F "type=customers"
Confirm the response returns an import/job identifier, then hit the corresponding status endpoint. If that loop works end-to-end, you understand the package well enough to build on it.
Keep it an adapter. Resist adding business rules to the controllers. If you need custom column mapping, transformation, or validation beyond the HTTP layer, implement it in the underlying import/export service or a dedicated action class, and let this package only translate HTTP to that call. Otherwise you will fork the module the first time you need to change behaviour.
Wrap the endpoints in your own façade. Expose your application's own routes that delegate to the module's services rather than letting clients call module routes directly. This gives you a stable public API contract, lets you version independently, and means an upstream breaking change is a one-file fix:
Route::middleware(['auth:sanctum', 'throttle:imports'])
->post('/v1/imports', [App\Http\Controllers\ImportController::class, 'store']);
Drive it from a Laravel HTTP client in tests and internal callers. Because it is an API adapter, Http::fake() based tests are the fastest way to pin the contract:
Http::fake(['*/api/imports' => Http::response(['id' => 42, 'status' => 'queued'], 202)]);
$this->postJson('/v1/imports', ['file' => UploadedFile::fake()->create('x.csv')])
->assertAccepted();
Queued imports plus polling or webhooks. Imports of any real size should not block the request. Configure the queue connection in the published config, run workers, and expose a status endpoint to the front end. For large files prefer a signed callback/webhook over aggressive polling; if the package does not ship one, add a listener on your job's completion event.
Multi-tenant scoping. Apply tenant/user scoping in your wrapper routes and in policies. A generic import endpoint that accepts an arbitrary type parameter is an obvious privilege-escalation surface — validate that the authenticated user is allowed to import that resource type.
Exports as streamed downloads. For exports, prefer returning a streamed or signed-URL response rather than materialising the whole file in memory. If the module queues exports, mirror the import pattern: request, receive an identifier, poll, then download from a temporary signed route.
Composition with the rest of the app. Wire the module's config into your environment file, publish the config, and pin the version in composer.json. If you need behaviour it does not support, look for a container binding or interface you can override in a service provider before considering a fork.
License is NOASSERTION. This is the single biggest risk. There is no declared license, which legally defaults to all rights reserved in many jurisdictions. Get written clarification from the maintainer, or treat the package as read-only reference and reimplement the small surface you need. Do not ship it to a client without resolving this.
Zero stars, zero dependents, single maintainer. Assume no community support and no compatibility guarantees. Pin to an exact version (composer require liberusoftware/import-export-api:1.2.3), commit the lock file, and consider vendoring or forking into your own namespace so an abandoned upstream does not block you. The last release: 2026-10-26 date in the metadata is in the future relative to normal release cadences — verify it against Packagist and the Git tags rather than trusting the listing.
Version and framework compatibility. Check the illuminate/* constraints in composer.json. Modules like this are frequently written against one Laravel major and silently break on the next. Run the test suite (if any) against your target version before adopting.
Auto-discovery collisions. Modular Liberu packages often register overlapping route prefixes or middleware groups. If route:list shows duplicate or shadowed routes, disable auto-discovery for the package and register the provider manually with your own prefix.
Upload limits are PHP limits. The number-one "the package is broken" report is actually upload_max_filesize / post_max_size in php.ini, plus Nginx client_max_body_size and any API gateway timeout. Check these before debugging the package.
Config caching. After publishing config, always php artisan config:clear in development. A stale cached config pointing at the wrong disk is a classic silent failure.
Queue and failure handling. Verify workers are running on the connection the config specifies, and that failed jobs are visible (php artisan queue:failed). Add your own alerting on failed import jobs — the module is unlikely to provide it.
Disk configuration. Confirm which filesystem disk is used for staging and temporary exports. local in a multi-server deployment will break polling and downloads; use S3 or a shared volume.
Idempotency and duplicates. Generic import endpoints rarely deduplicate. Add an idempotency key or a unique constraint on your side, or you will get double imports on retries and timeouts.
Memory on export. If exports are synchronous, large datasets will hit memory_limit. Check whether the implementation chunks or streams; if not, cap export size in your validation layer.
Extension points to prefer, in order: config values → container bindings over interfaces → published routes/views → subclassing the controller → forking. Debug with route:list -v, Laravel Telescope for the request/response cycle, and Log::debug around the adapter's delegation call to see exactly where it hands off.
How can I help you explore Laravel packages today?