Quando integri API, CRM e tool di marketing, i payload raramente sono “piatti”: liste dentro liste, oggetti dentro array e campi annidati ovunque. Con json array n8n puoi trasformare dati disordinati in insight pronti all’uso, senza scrivere un backend. In questa guida pratica impari a distinguere oggetti e array nella struttura items di n8n, a leggere i dati con espressioni (dot/bracket notation), a usare Set per selezionare e rinominare campi, Item Lists per fare split degli array, e Function/Function Item per manipolazioni più avanzate. Vedrai pattern ricorrenti per parsing di payload API in n8n, flatten di array e consolidamento finale, con esempi testati e snippet pronti. Chiudiamo con best practice su error handling, gestione array vuoti e performance su dataset grandi. Obiettivo: costruire pipeline affidabili e riutilizzabili che rendano il tuo team marketing più produttivo.

📚 Nuovo a n8n? Parti dalla guida completa: cos'è n8n e come funziona.

[IMG: Panoramica flusso: HTTP Request → Set (normalize) → Item Lists (split) → Function (transform) → Merge (consolidate) → Destinazione]


Fondamentali: oggetti vs array e dove “vivono” i dati in n8n

In n8n, ogni nodo riceve e produce un array di items. Ogni item ha una sezione json (e opzionalmente binary). Questo significa che lavorerai spesso con due livelli:

  • L’array di items prodotto/consumato dai nodi.
  • Gli array/oggetti all’interno di ciascun item.json.

Dove leggere i dati

  • $json: rappresenta il payload JSON dell’item corrente.
  • $node[“NomeNodo”].json: accede al json prodotto da un nodo precedente (utile quando vuoi “saltare” il contesto corrente).
  • $input.all(): in un Code/Function, recupera tutti gli items in ingresso.

Dot e bracket notation nelle espressioni

  • Dot notation: {{ $json.user.email }}
  • Bracket notation: {{ $json[“user”][“emails”][0] }}
    Usa bracket notation quando la chiave contiene spazi o caratteri speciali.

Quando serve il parsing esplicito

  • Se un nodo precedente ha già convertito la risposta in JSON (es. HTTP Request con “Response: JSON”), puoi accedere direttamente ai campi. Fai parsing manuale (JSON.parse) solo se ricevi testo grezzo.

Insight

  • Pensa al flusso come a trasformazioni successive dell’array di items. Spesso il “trucco” è portare l’array giusto “a livello item”, così ogni elemento viene processato in modo indipendente e prevedibile.

Accesso a sotto-array e campi profondi: espressioni sicure e default

Per un array JSON annidato in n8n come:

{
  "results": [
    { "id": 1, "domain": "esempio.com", "owner": { "name": "Anna" } },
    { "id": 2, "domain": "demo.io", "owner": { "name": "Luca" } }
  ],
  "meta": { "count": 2 }
}

Esempi pratici

  • Primo dominio: {{ $json.results[0].domain || ” }}
  • Nome proprietario del secondo: {{ $json.results[1].owner.name || ‘Sconosciuto’ }}
  • Conteggio risultati: {{ $json.meta.count || 0 }}

Indici e controlli di esistenza

  • Usa l’operatore OR (||) per default sicuri.
  • Verifica la lunghezza prima di indicizzare in Code:
const arr = $json.results || [];
const first = arr.length ? arr[0] : null;
return [{ json: { firstDomain: first?.domain || '' } }];

Ridurre la profondità

  • Se il payload è troppo annidato, crea un oggetto “normalizedEvent” o “normalizedLead” nel Set/Function, con solo i campi necessari per gli step successivi. Questo rende le espressioni più semplici e robuste.

Suggerimento

  • Mantieni i path coerenti in tutto il workflow; rinomina subito i campi strani (chiavi con spazi, notazioni atipiche) per evitare errori a valle.

Selezionare e rinominare campi con Set: il tuo “mapper” visivo

Il nodo Set è il coltellino svizzero per normalizzare i payload:

  • Mappare campi essenziali (es. title, url, createdAt).
  • Rinominare proprietà.
  • Rimuovere rumore prima degli step successivi.

Parametri utili (esatti)

  • Keep Only Set (keepOnlySet): se true, mantiene solo i campi che definisci nel Set.
  • Add Field: aggiungi/mappi campi nuovi con valori statici o espressioni.
  • Remove Fields (options.removeFields): rimuove esplicitamente campi indesiderati.

Esempio configurazione

  • Campo “title” = {{ $json.data.item.title }}
  • Campo “authorName” = {{ $json.data.item.owner.name }}
  • Campo “createdAtISO” = {{ $json.data.item.created_at }}
  • keepOnlySet = true per consegnare downstream solo ciò che serve.

Perché è importante

  • Selezionare campi con il nodo Set in n8n riduce complessità, errori e payload. E soprattutto rende leggibili le mappature per chiunque riveda il workflow.

[IMG: Nodo Set con keepOnlySet=true e mapping di 4 campi essenziali]


Split e flatten: lavorare con array con Item Lists e ricomporre i risultati

Quando ricevi un array e vuoi processare ogni elemento come item singolo, usa Item Lists.

Operazioni chiave (nodo Item Lists)

  • splitIntoItems: prende un array in un campo (es. “results”) e produce un item per elemento.
  • aggregate: fa l’opposto, ricompone molti items in un array unico.

Esempio: trasformare risposta API in singoli item

  • Item Lists → operation: splitIntoItems, property: results
  • Ora ogni item.json rappresenta un singolo elemento dell’array originale.

Flatten di array annidati

  • Se results contiene a sua volta un array (es. results[].tags), puoi usare un secondo pass di splitIntoItems sul campo tags quando serve iterare a quel livello.

Ricomposizione

  • Dopo elaborazioni per-item (Set/Function/HTTP), usa Item Lists con operation aggregate per ottenere di nuovo un array. In alternativa, usa un nodo Code Run Once For All Items:
const all = $input.all().map(i => i.json);
return [{ json: { items: all } }];

Consiglio

  • Dopo lo split, applica filtri/IF subito (es. elimina gli item incompleti). Meno rumore scorre nel workflow, più performante e stabile sarà la pipeline.

[IMG: Item Lists: splitIntoItems su “results” → Set → (opzionale) second split → aggregate]


Function e Function Item: quando serve codice (e come scriverlo bene)

Per manipolazioni personalizzate, usa un Code node (Function-like).

Modalità operative

  • Run Once For Each Item: trasforma ogni item singolarmente.
  • Run Once For All Items: lavora su tutti gli items insieme (batch), ideale per aggregazioni o prompt cumulativi.

Esempi utili
1) Mappatura di array di oggetti in n8n (per-item)

// Per ogni item, estrai solo id, domain e ownerName
const r = $json.results || [];
return r.map(e => ({ json: {
  id: e.id,
  domain: e.domain,
  ownerName: e.owner?.name || ''
}}));

2) Consolidare dati dopo split in n8n (batch)

// Combina tutti gli items in un array "rows" per export
const rows = $input.all().map(i => i.json);
return [{ json: { rows } }];

3) Gestione array vuoti e indici sicuri

const arr = Array.isArray($json.list) ? $json.list : [];
const firstValid = arr.find(x => x && x.active) || null;
return [{ json: { firstValid: firstValid || {} } }];

Best practice

  • Valori di default sempre presenti.
  • Evita side effect: restituisci nuovi oggetti, non mutare $json in-place se non necessario.
  • Log mirato: usa console.log in debug, poi rimuovi per produzione.

Pattern end‑to‑end: dal payload API all’output pulito

Scenario: API → estrai results[] → normalizza → invia a un CRM solo i campi essenziali.

Step-by-step
1) HTTP Request (Response: JSON)

  • Ottieni payload con { results: […] }.

2) Item Lists (splitIntoItems, property: results)

  • Ogni elemento dell’array diventa un item.

3) Set (keepOnlySet=true)

  • Mappa: id, domain, ownerName, createdAtISO.
  • Rinomina i campi secondo lo schema richiesto dal CRM (es. crmdomain, crmowner).

4) Function (Run Once For Each Item)

// Valida e arricchisci
const email = $json.ownerName ? `${$json.ownerName.replace(/\s+/g,'.')}@example.com` : '';
return [{ json: { ...$json, contactEmail: email } }];

5) Merge o aggregate (se serve ricomporre)

  • Se il CRM accetta bulk, usa un Code Run Once For All Items per creare un array rows.

6) HTTP Request (POST → CRM)

  • Invia i dati normalizzati.

[IMG: Canvas: HTTP → Item Lists(split) → Set → Function → (Aggregate) → HTTP(CRM)]

Perché funziona

  • Ogni step ha responsabilità chiara: split, normalize, validate, deliver. Il flusso rimane leggibile e testabile per i colleghi.

Error handling e casi spinosi: array vuoti, campi mancanti, tipologie

Array vuoti e campi mancanti

  • Prima di indicizzare, controlla la lunghezza: (arr && arr.length).
  • Default sicuri con || e operatori opzionali (?.) in Code.

Type mismatch

  • Quando un campo a volte è oggetto e a volte array, normalizza:
const tags = $json.tags;
const tagsArr = Array.isArray(tags) ? tags : (tags ? [tags] : []);
return [{ json: { ...$json, tags: tagsArr } }];

Validazioni a monte

  • Subito dopo lo split, elimina item incompleti:
const ok = $json.id && $json.domain;
if (!ok) { return []; } // drop item
return [{ json: $json }];

Unire rami e consolidare dati

  • Usa il Merge node per combinare flussi paralleli:
  • mode: Append, Wait, Merge By Index, Merge By Key (ad es. chiave id condivisa).
  • Scegli outputDataFrom: “both” o il lato preferito, e opzioni per gestire missing matches.

[IMG: Merge By Key su “id” per riunire arricchimento e dati originali]


Performance e manutenibilità: batching, filtri, debug e naming

Performance su array grandi

  • Filtra presto, riduci i campi con Set, limita l’intervallo temporalmente a monte.
  • Se devi processare migliaia di elementi, pensa a batch (Split In Batches) e a backpressure su integrazioni esterne.

Debug efficace

  • Ispeziona spesso l’anteprima $json, aggiungi un nodo Code temporaneo per loggare shape e size:
console.log('Items:', $input.all().length);
console.log('Keys:', Object.keys($json || {}));
return $input.all();

Nomenclatura e tracciabilità

  • Adotta nomi consistenti (normalized, crm, ext*).
  • Documenta in una nota del workflow i campi chiave e i path usati.

Modelli riutilizzabili

  • Trasforma i pattern ricorrenti (split→set→function) in sub‑workflow o template. Riduce errori e velocizza lo sviluppo.

[IMG: Best practice: Set (reduce fields) prima di richieste esterne per payload più piccoli]


Quick Takeaways

  • Tratta separatamente array di items (n8n) e array dentro item.json; accedi con $json e dot/bracket notation.
  • Usa Set come mapper: keepOnlySet per ridurre rumore, Add Field per rinominare/derivare campi.
  • Item Lists con splitIntoItems per processare ogni elemento e aggregate per ricomporre.
  • Function/Function Item abilitano logiche su misura; usa default e controlli per array vuoti.
  • Merge combina rami con modalità Append/Wait/By Index/By Key per consolidare dati.
  • Filtra e normalizza presto per performance; logga e testa path/espressioni durante lo sviluppo.

Conclusione

Lavorare bene con json array n8n significa dominare tre mosse: normalizzare, dividere e ricomporre. Con Set selezioni i campi che contano, con Item Lists porti gli array “a livello item” per processarli in sicurezza, e con Function colmi i gap di logica senza perdere leggibilità. Aggiungi pattern di dedup, validazioni e Merge per consolidare i flussi, e avrai pipeline robuste che riducono errori e tempi di lavorazione. Il valore per i marketer è immediato: meno tempo perso a “sistemare” dati e più focus su insight e azioni. Parti da un flusso, estrai un array reale, applica split→set→function, e misura il risparmio: è il primo passo verso automazioni più veloci, affidabili e facili da mantenere.


FAQ

1) Come estraggo un sotto‑array dal payload API?
Usa Item Lists con operation splitIntoItems sul campo che contiene l’array (es. results). Ogni elemento diventa un item separato, pronto per trasformazioni successive.

2) Come seleziono solo i campi utili?
Con il nodo Set imposta keepOnlySet=true e mappa i campi necessari (title, url, createdAt…). Puoi anche rinominare i campi per lo schema del tool di destinazione.

3) Quando serve Function invece di Set/Item Lists?
Usa Function/Function Item per logiche condizionali, default avanzati, flatten non banale o costruzione di output complessi (batch con Run Once For All Items).

4) Come evito errori con array vuoti?
Controlla sempre lunghezze e tipi: Array.isArray, arr.length e operatori di default (||). In caso di dati mancanti, droppa l’item o assegna valori sicuri.

5) Come ricompongo i dati dopo averli “splittati”?
Item Lists con operation aggregate oppure un Code Run Once For All Items che fa $input.all().map(i => i.json) e ritorna un array consolidato sotto una chiave (es. rows).


Ci dai un feedback?

Qual è l’array più ostico che hai dovuto trasformare di recente? Condividi l’esempio (sanificato) e le soluzioni adottate: aiutiamoci a creare pattern riutilizzabili che velocizzano il lavoro di tutti!

Vuoi automazioni AI su misura per la tua azienda?
Scopri la consulenza →