JSON API
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 + cesta | Názov | Vstup → odpoveď |
|---|---|---|
GET /importers | importers.index | ImporterResource[], ktoré používateľ smie vidieť |
GET /importers/{importer}/template | importers.template | format (xlsx|csv), locale (≤ 16, [A-Za-z_-]) → stiahnutie súboru (overuje View) |
GET /importers/{importer}/mappings | importers.mappings | SavedMappingResource[] |
DELETE /importers/{importer}/mappings/{name} | importers.mappings.destroy | {"deleted": true} 200 alebo {"deleted": false} 404 |
POST /importers/{importer}/sessions | sessions.store | multipart 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-sessions | sessions.files | files[] (≥ 1 súbor), locale → ImportSessionResource, 201 · obmedzené |
GET /sessions | sessions.index | importer (≤ 60), status[] (≤ 20 hodnôt SessionStatus), per_page (1 … 100, predvolene 20) → stránkované ImportSessionResource, najnovšie prvé |
GET /sessions/{session} | sessions.show | ImportSessionResource |
PATCH /sessions/{session}/source | sessions.source | sheet / sheet_index, delimiter, header_row → ImportSessionResource |
DELETE /sessions/{session} | sessions.destroy | 204 (zahodenie) |
GET /sessions/{session}/mapping | sessions.mapping | návrh mapovania |
PUT /sessions/{session}/mapping | sessions.map | mapping (text hlavičky alebo index od 0 → pole alebo null) alebo columns ([{column, field}] — vždy podľa indexu) → ImportSessionResource |
POST /sessions/{session}/mapping/save | sessions.mapping.save | name (1 … 60) → ImportSessionResource |
PUT /sessions/{session}/mode | sessions.mode | mode → ImportSessionResource |
POST /sessions/{session}/preview | sessions.preview.run | ImportSessionResource, 202 |
GET /sessions/{session}/preview | sessions.preview | ImportPreviewResource |
GET /sessions/{session}/rows | sessions.rows | status (invalid|duplicates|updates|creates|skips|all), per_page (1 … 100, predvolene 50), page → stránkované ImportRowResultResource |
GET /sessions/{session}/error-report | sessions.error-report | format (predvolene xlsx), locale (popisy reportu) → stiahnutie súboru |
POST /sessions/{session}/commit | sessions.commit | ImportBatchResource, 202 |
GET /batches/{batch} | batches.show | ImportBatchResource |
POST /batches/{batch}/cancel · /resume · /rollback | batches.cancel · batches.resume · batches.rollback | ImportBatchResource, 202 |
GET /batches/{batch}/records | batches.records | action (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/rollbackChyby
| Stav | Kedy |
|---|---|
| 422 | Validá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}. |
| 403 | authorize() odmietol alebo sa nenašiel vlastník. |
| 404 | Nezná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. |
| 409 | Nesprá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
| Rola | Kľúč konfigurácie | Predvolené | Dostane → výstup |
|---|---|---|---|
| vlastník | imports.resources.owner | ImportOwnerResource | Model vlastníka → {id, type: názov triedy}. |
| aktér | imports.resources.actor | ImportActorResource | Model aktéra → {id, type}. |
| záznam | imports.resources.record | ImportRecordResource | RecordReference — 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 kryptomienOdoslaní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.