Che cos'è JSON e come lo usi?

Pubblicato: 2022-08-14
Immagine del testo "JSON" sovrapposto al monitor di un computer
Maria Vonotna/Shutterstock.com

JSON (JavaScript Object Notation) è un formato standardizzato per rappresentare dati strutturati. Sebbene JSON sia nato dal linguaggio di programmazione JavaScript, ora è un metodo onnipresente di scambio di dati tra i sistemi. La maggior parte delle API moderne accetta richieste JSON ed emette risposte JSON, quindi è utile avere una buona conoscenza pratica del formato e delle sue funzionalità.

In questo articolo spiegheremo cos'è JSON, come esprime diversi tipi di dati e come puoi produrlo e utilizzarlo nei linguaggi di programmazione più diffusi. Tratteremo anche alcune delle limitazioni di JSON e le alternative emerse.

Nozioni di base su JSON

JSON è stato originariamente ideato da Douglas Crockford come formato stateless per la comunicazione di dati tra browser e server. All'inizio degli anni 2000, i siti Web stavano iniziando a recuperare in modo asincrono dati extra dal proprio server, dopo il caricamento iniziale della pagina. Essendo un formato basato su testo derivato da JavaScript, JSON ha semplificato il recupero e l'utilizzo dei dati all'interno di queste applicazioni. La specifica è stata infine standardizzata come ECMA-404 nel 2013.

JSON viene sempre trasmesso come stringa. Queste stringhe possono essere decodificate in una gamma di tipi di dati di base, inclusi numeri, booleani, matrici e oggetti. Ciò significa che le gerarchie e le relazioni degli oggetti possono essere conservate durante la trasmissione, quindi riassemblate sul lato ricevente in modo appropriato per l'ambiente di programmazione.

Un esempio JSON di base

Questa è una rappresentazione JSON di un post del blog:

 {
    "id": 1001,
    "title": "Cos'è JSON?",
    "autore": {
        "id": 1,
        "nome": "James Walker"
    },
    "tags": ["api", "json", "programmazione"],
    "pubblicato": falso,
    "pubblicatoTimestamp": null
}

Questo esempio mostra tutti i tipi di dati JSON. Illustra anche la concisione dei dati in formato JSON, una delle caratteristiche che li ha resi così interessanti per l'uso nelle API. Inoltre, JSON è relativamente facile da leggere così com'è, a differenza di formati più dettagliati come XML.

Tipi di dati JSON

Sei tipi di dati possono essere rappresentati in modo nativo in JSON:

  • Stringhe : le stringhe vengono scritte tra virgolette doppie; è possibile eseguire l'escape dei caratteri utilizzando le barre inverse.
  • Numeri : i numeri vengono scritti come cifre senza virgolette. Puoi includere un componente frazionario per denotare un float. La maggior parte delle implementazioni di analisi JSON presuppone un numero intero quando non è presente la virgola decimale.
  • Booleani : i valori letterali true e false sono supportati.
  • Null : il valore letterale null può essere utilizzato per indicare un valore vuoto o omesso.
  • Matrici : una matrice è un semplice elenco indicato da parentesi quadre. Ogni elemento nell'elenco è separato da una virgola. Gli array possono contenere un numero qualsiasi di elementi e possono utilizzare tutti i tipi di dati supportati.
  • Oggetti : gli oggetti vengono creati tra parentesi graffe. Sono una raccolta di coppie chiave-valore in cui le chiavi sono stringhe, racchiuse tra virgolette doppie. Ogni chiave ha un valore che può accettare qualsiasi tipo di dati disponibile. È possibile annidare gli oggetti per creare gerarchie a cascata. Una virgola deve seguire ogni valore, a significare la fine di quella coppia chiave-valore.

I parser JSON convertono automaticamente questi tipi di dati in strutture appropriate alla loro lingua. Ad esempio, non è necessario eseguire manualmente il cast di id su un numero intero. L'analisi dell'intera stringa JSON è sufficiente per associare i valori al formato dati originale.

Semantica e Validazione

JSON ha alcune regole che devono essere rispettate quando codifichi i tuoi dati. Le stringhe che non rispettano la sintassi non saranno analizzabili dai consumatori.

È particolarmente importante prestare attenzione alle virgolette attorno alle stringhe e alle chiavi degli oggetti. È inoltre necessario assicurarsi che venga utilizzata una virgola dopo ogni voce in un oggetto o una matrice. Tuttavia, JSON non consente una virgola finale dopo l'ultima voce: includerne una involontariamente è una causa comune di errori di convalida. La maggior parte degli editor di testo metterà in evidenza i problemi di sintassi per te, aiutando a scoprire gli errori.

Nonostante questi punti di scatto comuni, JSON è uno dei formati di dati più facili da scrivere a mano. La maggior parte delle persone trova la sintassi rapida e conveniente una volta acquisita familiarità con essa. Nel complesso JSON tende a essere meno soggetto a errori rispetto a XML, dove i tag di apertura e chiusura non corrispondenti, le dichiarazioni di schema non valide e i problemi di codifica dei caratteri spesso causano problemi.

Designazione del contenuto JSON

L'estensione .json viene normalmente utilizzata quando JSON viene salvato in un file. Il contenuto JSON ha il tipo MIME standardizzato application/json , sebbene text/json venga talvolta utilizzato per motivi di compatibilità. Al giorno d'oggi dovresti fare affidamento su application/json per le intestazioni HTTP Accept e Content-Type .

La maggior parte delle API che utilizzano JSON incapsula tutto in un oggetto di primo livello:

 {
    "errore": 1000
}

Tuttavia, questo non è richiesto: un tipo letterale è valido come nodo di primo livello in un file, quindi anche i seguenti esempi sono tutti JSON validi:

 1000 
 VERO 
 nullo

Decodificheranno nei rispettivi scalari nel tuo linguaggio di programmazione.

Lavorare con JSON

La maggior parte dei linguaggi di programmazione ha il supporto JSON integrato. Ecco come interagire con i dati JSON in alcuni ambienti popolari.

JavaScript

In JavaScript i JSON.stringify() e JSON.parse() vengono utilizzati per codificare e decodificare stringhe JSON:

 post costante = {
    id : 1001 ,
    titolo : "Cos'è JSON?" ,
    autore : {
        id : 1 ,
        nome : "James Walker"
    }
} ;

const encodedJson = JSON. stringify ( postare ) ;

// {"id": 1001, "title": "Cos'è JSON?", ...}
consolle. log ( encodedJson ) ;

const decodificatoJson = JSON. parse ( encodedJson ) ;

// James Walker
consolle. log ( decodedJson.autore.nome ) ; _

PHP

Le funzioni equivalenti in PHP sono json_encode() e json_decode() :

 $post = [
    "id" => 1001 ,
    "title" => "Cos'è JSON?" ,
    "autore" => [
        "id" => 1 ,
        "nome" => "James Walker"
    ]
] ;

$encodedJson = json_encode ( $post ) ;

// {"id": 1001, "title": "Cos'è JSON?", ...}
eco $encodedJson ;

$decodedJson = json_decode ( $encodedJson , true ) ;

// James Walker
echo $decodedJson [ "autore" ] [ "nome" ] ;

Pitone

Python fornisce json.dumps() e json.loads() rispettivamente per serializzare e deserializzare:

 importa json

posta = {
    "id" : 1001 ,
    "title" : "Cos'è JSON?" ,
    "autore" : {
        "id" : 1 ,
        "nome" : "James Walker"
    }
}

codificatoJson = json. discariche ( posta )

# {"id": 1001, "title": "Cos'è JSON?", ...}
print ( encodedJson )

decodificatoJson = json. carichi ( encodedJson )

# Giacomo Walker
print ( decodificatoJson [ "autore" ] [ "nome" ] )

Rubino

Ruby offre JSON.generate e JSON.parse :

 richiedono "json"

posta = {
    "id" => 1001 ,
    "title" => "Cos'è JSON?" ,
    "autore" => {
        "id" => 1 ,
        "nome" => "James Walker"
    }
}

codificatoJson = JSON. generare ( pubblicare )

# {"id": 1001, "title": "Cos'è JSON?", ...}
mette encodedJson

decodificatoJson = JSON. parse ( encodedJson )

# Giacomo Walker
mette decodedJson [ "author" ] [ "name" ]

Limitazioni JSON

JSON è un formato leggero che si concentra sulla trasmissione dei valori all'interno della struttura dei dati. Ciò lo rende veloce da analizzare e facile da usare, ma significa che ci sono degli svantaggi che possono causare frustrazione. Ecco alcuni dei maggiori problemi.

Non ci sono commenti

I dati JSON non possono includere commenti. La mancanza di annotazioni riduce la chiarezza e ti costringe a mettere la documentazione altrove. Ciò può rendere JSON inadatto per situazioni come i file di configurazione, in cui le modifiche non sono frequenti e gli scopi dei campi potrebbero non essere chiari.

Nessuno schema

JSON non ti consente di definire uno schema per i tuoi dati. Non c'è modo di imporre che id sia un campo intero obbligatorio, ad esempio. Ciò può portare a strutture di dati non intenzionalmente malformate.

Nessun riferimento

I campi non possono fare riferimento ad altri valori nella struttura dati. Questo spesso provoca ripetizioni che aumentano le dimensioni del file. Tornando all'esempio del post del blog di prima, potresti avere un elenco di post del blog come segue:

 {
    "post": [
        {
            "id": 1001,
            "title": "Cos'è JSON?",
            "autore": {
                "id": 1,
                "nome": "James Walker"
            }
        },
        {
            "id": 1002,
            "title": "Cos'è SaaS?",
            "autore": {
                "id": 1,
                "nome": "James Walker"
            }
        }
    ]
}

Entrambi i post hanno lo stesso autore ma le informazioni associate a quell'oggetto hanno dovuto essere duplicate. In un mondo ideale, le implementazioni del parser JSON sarebbero in grado di produrre la struttura mostrata sopra da un input simile al seguente:

 {
    "post": [
        {
            "id": 1001,
            "title": "Cos'è JSON?",
            "author": "{{ .authors.james }}"
        },
        {
            "id": 1002,
            "title": "Cos'è SaaS?",
            "author": "{{ .authors.james }}"
        }
    ],
    "autori": {
        "giacomo": {
            "id": 1,
            "nome": "James Walker"
        }
    }
}

Questo non è attualmente possibile con JSON standard.

Nessun tipo di dati avanzato

I sei tipi di dati supportati omettono molti tipi comuni di valore. JSON non può archiviare in modo nativo date, orari o punti di geolocalizzazione, quindi è necessario decidere il proprio formato per queste informazioni.

Ciò provoca discrepanze scomode e casi limite. Se la tua applicazione gestisce i timestamp come stringhe, come 2022-07-01T12:00:00+00:00 , ma un'API esterna presenta l'ora come secondi dopo l'epoca Unix – 1657287000 – dovrai ricordare quando utilizzare ciascuno dei formati.

Alternative JSON

YAML è l'alternativa JSON principale. È un superset del formato che ha una presentazione più leggibile, tipi di dati personalizzati e supporto per i riferimenti. Ha lo scopo di affrontare la maggior parte delle sfide di usabilità associate a JSON.

YAML ha visto un'ampia adozione per i file di configurazione e all'interno di DevOps, IaC e strumenti di osservabilità. È usato meno frequentemente come formato di scambio di dati per le API. La relativa complessità di YAML significa che è meno accessibile ai nuovi arrivati. Piccoli errori di sintassi possono causare errori di analisi confusi.

I buffer di protocollo (protobuf) sono un altro concorrente JSON emergente progettato per serializzare dati strutturati. I protobuf hanno dichiarazioni del tipo di dati, campi obbligatori e supporto per la maggior parte dei principali linguaggi di programmazione. Il sistema sta guadagnando popolarità come un modo più efficiente di trasmettere dati sulle reti.

Riepilogo

JSON è un formato di rappresentazione dei dati basato su testo che può codificare sei diversi tipi di dati. JSON è diventato un punto fermo dell'ecosistema di sviluppo software; è supportato da tutti i principali linguaggi di programmazione ed è diventata la scelta predefinita per la maggior parte delle API REST sviluppate negli ultimi due decenni.

Sebbene la semplicità di JSON faccia parte della sua popolarità, impone anche limitazioni su ciò che puoi ottenere con il formato. La mancanza di supporto per schemi, commenti, riferimenti a oggetti e tipi di dati personalizzati significa che alcune applicazioni scopriranno che superano ciò che è possibile con JSON. Alternative più giovani come YAML e Protobuf hanno aiutato ad affrontare queste sfide, mentre XML rimane un contendente per le applicazioni che vogliono definire uno schema di dati e non si preoccupano della verbosità.