NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

Hotové JSON API pre JavaScript frontend alebo mobilnú aplikáciu. Predvolene je vypnuté:

IMPORTS_ROUTES=on
  • Prefix imports.routes.prefix (api/imports), middleware imports.routes.middleware (api, auth), názvy ciest imports.*. Ak chcete súbor ciest vlastniť, publikujte imports-routes.
  • Vlastníka požiadavky určí imports.routes.owner_resolver, ResolvesImportOwner (resolve(Request $request): ?Model) — predvolene prihlásený používateľ. Bez vlastníka → 403.
  • Každý endpoint ide cez Imports::for($owner)->by($request->user()), takže relácia či dávka iného vlastníka je 404 a o zvyšku rozhodne authorize() importéra — každé čítanie sa pýta na View.
  • Vstup overujú FormRequests a používajú sa len overené dáta. Odpovede sú preložené do jazyka požiadavky.
  • Oba endpointy na nahrávanie obmedzuje rate limiter imports-upload: imports.routes.upload_limit za minútu (predvolene 10, 0 = bez limitu), podľa id prihláseného používateľa, pri hosťovi podľa IP.
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use RoundlyConsulting\Imports\Contracts\ResolvesImportOwner;

// A team-owned API: the owner is the user's current team.
final class CurrentTeamOwner implements ResolvesImportOwner
{
    public function resolve(Request $request): ?Model
    {
        return $request->user()?->currentTeam;
    }
}

// config/imports.php
'routes' => ['enabled' => 'on', 'owner_resolver' => App\Imports\CurrentTeamOwner::class],

Endpointy

Metóda + cestaNázovVstup → odpoveď
GET /importersimporters.indexImporterResource[], ktoré používateľ smie vidieť
GET /importers/{importer}/templateimporters.templateformat (xlsx|csv), locale (≤ 16, [A-Za-z_-]) → stiahnutie súboru (overuje View)
GET /importers/{importer}/mappingsimporters.mappingsSavedMappingResource[]
DELETE /importers/{importer}/mappings/{name}importers.mappings.destroy{"deleted": true} 200 alebo {"deleted": false} 404
POST /importers/{importer}/sessionssessions.storemultipart file (povinné), sheet (≤ 31) alebo sheet_index (1 … 1000), delimiter (, ; | tab), header_row (1 … 1000), locale, mode (skip|update|create_new) → ImportSessionResource, 201 · obmedzené
POST /importers/{importer}/file-sessionssessions.filesfiles[] (≥ 1 súbor), locale → ImportSessionResource, 201 · obmedzené
GET /sessionssessions.indeximporter (≤ 60), status[] (≤ 20 hodnôt SessionStatus), per_page (1 … 100, predvolene 20) → stránkované ImportSessionResource, najnovšie prvé
GET /sessions/{session}sessions.showImportSessionResource
PATCH /sessions/{session}/sourcesessions.sourcesheet / sheet_index, delimiter, header_row → ImportSessionResource
DELETE /sessions/{session}sessions.destroy204 (zahodenie)
GET /sessions/{session}/mappingsessions.mappingnávrh mapovania
PUT /sessions/{session}/mappingsessions.mapmapping (text hlavičky alebo index od 0 → pole alebo null) alebo columns ([{column, field}] — vždy podľa indexu) → ImportSessionResource
POST /sessions/{session}/mapping/savesessions.mapping.savename (1 … 60) → ImportSessionResource
PUT /sessions/{session}/modesessions.modemode → ImportSessionResource
POST /sessions/{session}/previewsessions.preview.runImportSessionResource, 202
GET /sessions/{session}/previewsessions.previewImportPreviewResource
GET /sessions/{session}/rowssessions.rowsstatus (invalid|duplicates|updates|creates|skips|all), per_page (1 … 100, predvolene 50), page → stránkované ImportRowResultResource
GET /sessions/{session}/error-reportsessions.error-reportformat (predvolene xlsx), locale (popisy reportu) → stiahnutie súboru
POST /sessions/{session}/commitsessions.commitImportBatchResource, 202
GET /batches/{batch}batches.showImportBatchResource
POST /batches/{batch}/cancel · /resume · /rollbackbatches.cancel · batches.resume · batches.rollbackImportBatchResource, 202
GET /batches/{batch}/recordsbatches.recordsaction (created|linked|updated), per_page (1 … 100, predvolene 50) → riadky evidencie

GET /sessions vypíše relácie vlastníka, ktoré používateľ smie vidieť — importér, ktorý vidieť nesmie, je 403, neznámy 404. Eager-loaduje owner, actor a batch a klient, ktorý stratil id relácie, tu nájde svoje otvorené náhľady.

# Authenticated as your api + auth middleware expects; the prefix is api/imports
curl -F [email protected]  https://app.test/api/imports/importers/assets/sessions -H 'Accept: application/json'
curl -X PUT  https://app.test/api/imports/sessions/12/mapping -H 'Content-Type: application/json' \
     -d '{"columns": [{"column": 0, "field": "asset_tag"}, {"column": 1, "field": "name"}]}'
curl -X POST https://app.test/api/imports/sessions/12/preview
curl         "https://app.test/api/imports/sessions/12/rows?status=invalid&per_page=50"
curl -X POST https://app.test/api/imports/sessions/12/commit
curl         https://app.test/api/imports/batches/5
curl -X POST https://app.test/api/imports/batches/5/rollback

Chyby

StavKedy
422Validácia požiadavky; chybné mapovanie — {message, errors}, chyby mapovania s kľúčmi columns.<column> / fields.<field>. Aj odmietnutý súbor, chýbajúci hárok, režim, ktorý importér nemá, odmietnuté alebo nadlimitné uložené mapovanie — {message}.
403authorize() odmietol alebo sa nenašiel vlastník.
404Neznámy importér, relácia či dávka iného vlastníka alebo chýbajúca, prípadne id, ktoré nemôže byť kľúčom tabuliek balíka — overené pred akýmkoľvek dopytom.
409Nesprávny stav, zastaraný náhľad, expirovaná relácia, zmazaný súbor, iný bežiaci import, uzavreté okno na vrátenie.

Relácia

{
  "id": 12, "importer": {"key": "assets", "label": "Assets"}, "kind": "rows",
  "status": "previewed", "status_label": "Previewed", "format": "xlsx",
  "file": {"name": "assets.xlsx", "size": 18234}, "sheet": "Assets",
  "sheets": [{"name": "Assets", "index": 1, "visible": true}], "delimiter": null, "header_row": 1,
  "headers": ["Asset tag", "Name", "Column C"],
  "mapping": [{"column": 0, "field": "asset_tag"}, {"column": 1, "field": "name"}],
  "mode": "skip", "data_rows": 50,
  "counts": {"total": 50, "valid": 47, "invalid": 2, "duplicates": 1, "duplicates_in_file": 0, "matched": 1,
             "creates": 47, "updates": 0, "skips": 1, "template_rows": 0, "blank_rows": 0},
  "progress": {"processed": 50, "total": 50, "percent": 100}, "errors": 2, "batch_id": null,
  "expires_at": "2026-11-10T09:00:00+00:00", "can": {"commit": true, "rollback": false},
  "owner": {"id": 7, "type": "Team"}, "actor": {"id": 3, "type": "User"}, "created_at": "…"
}

Nikdy disk, cesta ani kľúč zámku. Príznaky can sa riadia pravidlami, ktoré vynucujú akcie: commit — v stave previewed a neexpirovaná; rollback — beh skončil bez vrátenia alebo so zlyhaným vrátením na zopakovanie, v rámci okna na vrátenie.

Ďalšie resources

  • ImportPreviewResource — counts, plan {creates, updates, skips}, update_notice (preložené, null bez aktualizácií), mode, unmapped_columns (indexy od 0).
  • ImportRowResultResource — row, status, outcome, label (dávky súborov: názov položky), errors [{field, column (písmeno), code, message, value}], match (odkaz na záznam) a changes [{field, from, to}] pri aktualizáciách.
  • ImportBatchResource — id, session_id, status, progress {processed, total, percent, phase}, summary {created, linked, updated, skipped, failed, reclassified, duplicates, invalid, duration}, undo_until, can_rollback, rollback_status, rollback (null, kým sa vrátenie nedokončí alebo nezlyhá), actor.
  • ImporterResource — key, label, kind, fields [{name, label, type, required, options, example, help, aliases, format, in_template}], modes, default_mode, formats, extensions (importéry súborov).
  • SavedMappingResource — name, importer, columns (normalizovaná hlavička → pole), updated_at.

Návrh mapovania (GET /sessions/{session}/mapping):

{"data": {
  "columns": [{"index": 0, "header": "Inventárne č.", "field": "asset_tag", "confidence": 0.98, "source": "label", "fuzzy": false}],
  "unmapped_required": [], "ignored_columns": [3], "saved_mapping": null, "complete": true
}}

Riadky evidencie (GET /batches/{batch}/records):

{"data": [{"row": 2, "action": "created", "record": {"id": 41, "type": "Asset"}, "rolled_back": false, "rollback_outcome": null}],
 "meta": {"current_page": 1, "last_page": 1, "total": 47}}

Resources pre odkazy — žiadne názvy tried v odpovediach

RolaKľúč konfiguráciePredvolenéDostane → výstup
vlastníkimports.resources.ownerImportOwnerResourceModel vlastníka → {id, type: názov triedy}.
aktérimports.resources.actorImportActorResourceModel aktéra → {id, type}.
záznamimports.resources.recordImportRecordResourceRecordReference — uložená morph dvojica, bez dopytu; zmazaný záznam sa stále vykreslí → {id, type}.
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

final class TeamReference extends JsonResource
{
    public function toArray(Request $request): array
    {
        return ['id' => $this->resource->getKey(), 'name' => $this->resource->name];
    }
}

// config/imports.php
'resources' => ['owner' => App\Http\Resources\TeamReference::class],

Hodnota, ktorá nie je inštanciovateľnou podtriedou JsonResource, vyhodí InvalidImportsConfigurationException s názvom kľúča; prázdna hodnota znamená predvolenú triedu. Ak váš resource číta vzťah, na zoznamoch ho eager-loadujte.

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.