Import and export Resource data
Declare transfer columns and verify scope, validation, and import results.
Import and export Resource data
Start with the tenant-owned Example from Create development data. Its normal create path needs only a name; organization-owned Resources require additional target handling.
Declare safe columns
Add these imports and members to src/Models/Example.php. Do not replace the whole generated model:
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder;
use Nexia\Laravel\ResourceTransfer\Concerns\ExportImportable;
use Nexia\ResourceTransfer\TransferSchema;
// Add inside the generated tenant-owned Example model; retain its other traits.
use ExportImportable;
public static function transferColumns(TransferSchema $schema): TransferSchema
{
return $schema->field('name', 'workshop.example.name.label', required: true);
}
public static function transferExportQuery(?Authenticatable $actor = null): Builder
{
abort_if($actor === null, 403);
return static::query()->visibleTo($actor);
}The default transfer scope is tenant. The generated controller already emits meta.resource_transfer; preserve it and the list's transfer integration. The host handles file formats and the App handles its own data. Do not expose numeric keys, tenant IDs, secrets or unrelated App fields as editable columns.
Verify through the list
- Synchronize using project
nexia dev. - Give the test actor tenant-level
system.data.export/system.data.importand the appropriate Example read/create permissions. - Open Examples. Export a small authorized set and compare it with the list; records hidden by Policy must stay absent.
- Download the offered import template, add one synthetic name, preview and execute the import. Reload the list and check per-row results.
- Check empty required names, denied users and duplicates. Import is create-only, not an upsert. A field declared with
TransferSchema::key()identifies duplicates;nameabove is deliberately not unique.
Default limits are 10,000 exported rows and 1,000 imported rows per model declaration. Read the returned metadata for the active limits and formats. A partial import result is not an all-or-nothing business transaction; use returned row outcomes for correction.
Preserve your domain rules
createFromImport(array $attributes) is the App-owned creation hook. Override it when normal creation needs additional validation, derived values or related writes; reuse the same domain operation as the API. The default simply creates the model. Request-only validation is not automatically executed here.
For legal-entity-owned models, set transferScope() to self::TRANSFER_SCOPE_LEGAL_ENTITY, constrain transferExportQuery() to authorized records, and derive the import owner from trusted scope. Do not accept arbitrary organization IDs from a spreadsheet. Test cross-organization access before exposing transfer.
TransferSchema supports field, key, references and export restrictions. Custom export sources implement the SDK ResourceTransferExportSourceContribution and ResourceTransferExportSource contracts; their queries still need actor authorization. Use the installed SDK definitions for exact overloads.