Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Tipi GraphQL
GraphQL supporta molti tipi diversi. Come hai visto nella sezione precedente, i tipi definiscono la forma o il comportamento dei dati. Sono gli elementi costitutivi fondamentali di uno schema GraphQL. 
I tipi possono essere classificati in input e output. Gli input sono tipi che possono essere passati come argomento per i tipi di oggetti speciali (Query,, ecc.)Mutation, mentre i tipi di output vengono utilizzati strettamente per archiviare e restituire dati. Di seguito è riportato un elenco di tipi e delle relative categorizzazioni:
                
                
                
                
                
                
            - 
                  Oggetti: un oggetto contiene campi che descrivono un'entità. Ad esempio, un oggetto potrebbe essere qualcosa come un oggetto bookcon campi che ne descrivono le caratteristiche comeauthorNamepublishingYear, ecc. Sono strettamente tipi di output.
 
- 
                  Scalari: sono tipi primitivi come int, string, ecc. In genere vengono assegnati ai campi. Usando il authorNamecampo come esempio, potrebbe essere assegnato loStringscalare per memorizzare un nome come «John Smith». Gli scalari possono essere sia di tipo di input che di output.
 
- 
                  Ingressi: gli input consentono di passare un gruppo di campi come argomento. Sono strutturati in modo molto simile agli oggetti, ma possono essere passati come argomenti a oggetti speciali. Gli input consentono di definire scalari, enumerazioni e altri input nel relativo ambito. Gli input possono essere solo tipi di input. 
- 
                  Oggetti speciali: gli oggetti speciali eseguono operazioni di modifica dello stato e svolgono la maggior parte del lavoro pesante del servizio. Esistono tre tipi di oggetti speciali: interrogazione, mutazione e sottoscrizione. Le query in genere recuperano i dati; le mutazioni manipolano i dati; le sottoscrizioni si aprono e mantengono una connessione bidirezionale tra client e server per una comunicazione costante. Gli oggetti speciali non vengono né input né output date le loro funzionalità. 
- 
                  Enumerazioni: le enumerazioni sono elenchi predefiniti di valori legali. Se chiami un enum, i suoi valori possono essere solo quelli definiti nel suo ambito. Ad esempio, se aveste un enum chiamato che trafficLightsrappresenta un elenco di segnali stradali, potrebbe avere valori comeredLightegreenLightma no.purpleLightUn vero semaforo avrà solo un certo numero di segnali, quindi puoi usare l'enum per definirli e forzarli a essere gli unici valori legali durante il riferimento.trafficLightGli enum possono essere sia di tipo di input che di output.
 
- 
                  Unioni/interfacce: le unioni consentono di restituire uno o più elementi in una richiesta a seconda dei dati richiesti dal client. Ad esempio, se si dispone Bookdi un tipo con untitlecampo e unAuthortipo con unnamecampo, è possibile creare un'unione tra entrambi i tipi. Se il cliente volesse cercare in un database la frase «Giulio Cesare», il sindacato potrebbe restituire Giulio Cesare (l'opera di William Shakespeare) tratto daBooktitlee Giulio Cesare (l'autore di Commentarii de Bello Gallico) dal.AuthornameLe unioni possono essere solo tipi di output.
 Le interfacce sono insiemi di campi che gli oggetti devono implementare. È un po' simile alle interfacce nei linguaggi di programmazione come Java, in cui è necessario implementare i campi definiti nell'interfaccia. Ad esempio, supponiamo che tu abbia creato un'interfaccia chiamata Bookche contenesse untitlecampo. Supponiamo che in seguito tuNovelabbia creato un tipo chiamato implementatoBook.NovelDovresti includere untitlecampo. Tuttavia,Novelpotresti includere anche altri campi non presenti nell'interfaccia comepageCountoISBN. Le interfacce possono essere solo tipi di output.
 
 Le sezioni seguenti spiegheranno come funziona ogni tipo in GraphQL.
               Oggetti
               Gli oggetti GraphQL sono il tipo principale che vedrai nel codice di produzione. In GraphQL, puoi pensare a un oggetto come a un raggruppamento di campi diversi (simili alle variabili in altri linguaggi), con ogni campo definito da un tipo (tipicamente uno scalare o un altro oggetto) che può contenere un valore. Gli oggetti rappresentano un'unità di dati che può essere recuperata/manipolata dall'implementazione del servizio.
               I tipi di oggetti vengono dichiarati utilizzando la parola chiave. Type Modifichiamo leggermente il nostro esempio di schema:
               type Person {
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
               I tipi di oggetti qui sono Person eOccupation. Ogni oggetto ha i propri campi con i propri tipi. Una caratteristica di GraphQL è la possibilità di impostare campi su altri tipi. Puoi vedere che il occupation campo Person contiene un tipo di Occupation oggetto. Possiamo fare questa associazione perché GraphQL descrive solo i dati e non l'implementazione del servizio.
             
               Scalari
               Gli scalari sono essenzialmente tipi primitivi che contengono valori. Nel AWS AppSync, esistono due tipi di scalari: gli scalari e gli AWS AppSync scalari GraphQL predefiniti. Gli scalari vengono in genere utilizzati per memorizzare i valori dei campi all'interno dei tipi di oggetti. I tipi GraphQL predefiniti includonoInt,Float, StringBoolean, e. ID Usiamo nuovamente l'esempio precedente:
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
               Individuando i title campi name e, entrambi contengono uno String scalare. Namepotrebbe restituire un valore di stringa come "John Smith" e il titolo potrebbe restituire qualcosa come "»firefighter. Alcune implementazioni GraphQL supportano anche scalari personalizzati che utilizzano la Scalar parola chiave e implementano il comportamento del tipo. Tuttavia, AWS AppSync attualmente non supporta scalari personalizzati. Per un elenco di scalari, vedi Tipi scalari in. AWS AppSync
             
               
               A causa del concetto di tipi di input e output, esistono alcune restrizioni quando si passano argomenti. I tipi che di solito devono essere passati, in particolare gli oggetti, sono limitati. È possibile utilizzare il tipo di input per aggirare questa regola. Gli input sono tipi che contengono scalari, enumerazioni e altri tipi di input.
               Gli input sono definiti utilizzando la parola chiave: input
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input personInput { 
  id: ID!
  name: String
  age: Int
  occupation: occupationInput
}
input occupationInput {
  title: String
}
               Come puoi vedere, possiamo avere input separati che imitano il tipo originale. Questi input verranno spesso utilizzati nelle operazioni sul campo in questo modo:
               type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input occupationInput {
  title: String
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
               Nota come stiamo ancora passando occupationInput al posto di Occupation creare unPerson. 
               Questo è solo uno scenario per gli input. Non hanno necessariamente bisogno di copiare gli oggetti in scala 1:1e, nel codice di produzione, molto probabilmente non lo userete in questo modo. È buona norma sfruttare gli schemi GraphQL definendo solo ciò che è necessario inserire come argomenti.
               Inoltre, gli stessi input possono essere utilizzati in più operazioni, ma non è consigliabile farlo. Ogni operazione dovrebbe idealmente contenere una propria copia unica degli input nel caso in cui i requisiti dello schema cambino.
             
               Oggetti speciali
               GraphQL riserva alcune parole chiave per oggetti speciali che definiscono parte della logica aziendale relativa al modo in cui lo schema recupererà/manipolerà i dati. Al massimo, può esserci una di ciascuna di queste parole chiave in uno schema. Fungono da punti di ingresso per tutti i dati richiesti che i tuoi clienti eseguono sul tuo servizio GraphQL. 
               Gli oggetti speciali vengono definiti anche utilizzando la type parola chiave. Sebbene vengano utilizzati in modo diverso dai normali tipi di oggetti, la loro implementazione è molto simile.
               
                  - Queries
- 
                        Le query sono molto simili alle GEToperazioni in quanto eseguono un recupero di sola lettura per ottenere dati dalla fonte. In GraphQL,Querydefinisce tutti i punti di ingresso per i client che effettuano richieste verso il tuo server. Ci sarà sempre un'implementazione GraphQLQuerynella tua implementazione GraphQL.
 Ecco i Querytipi di oggetti modificati che abbiamo usato nel nostro precedente esempio di schema:
 type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
type Query {                                   
  people: [Person]
}
 Il nostro Querycontiene un campo chiamatopeopleche restituisce un elenco diPersonistanze dalla fonte di dati. Supponiamo di dover modificare il comportamento della nostra applicazione e ora dobbiamo restituire un elenco delle soleOccupationistanze per uno scopo separato. Potremmo semplicemente aggiungerlo alla query:
 type Query {                                   
  people: [Person]
  occupations: [Occupation]
}
 In GraphQL, possiamo trattare la nostra query come l'unica fonte di richieste. Come puoi vedere, questo è potenzialmente molto più semplice  RESTful  delle implementazioni che potrebbero utilizzare endpoint diversi per ottenere lo stesso risultato (e). .../api/1/people.../api/1/occupations
 Supponendo di avere un'implementazione del resolver per questa query, ora possiamo eseguire una query vera e propria. Sebbene il Querytipo esista, dobbiamo chiamarlo esplicitamente affinché venga eseguito nel codice dell'applicazione. Questo può essere fatto usando laqueryparola chiave:
 query getItems {
   people {
      name
   }
   occupations {
      title
   }
}
 Come puoi vedere, questa query viene chiamata getItemse restituiscepeople(un elenco diPersonoggetti) eoccupations(un elenco diOccupationoggetti). Nelpeople, stiamo restituendo solo ilnamecampo di ciascunoPerson, mentre stiamo restituendo iltitlecampo di ciascunoOccupation. La risposta potrebbe essere simile a questa:
 {
  "data": {
    "people": [
      {
        "name": "John Smith"
      },
      {
        "name": "Andrew Miller"
      },
      .
      .
      .
    ],
    "occupations": [
      {
        "title": "Firefighter"
      },
      {
        "title": "Bookkeeper"
      },
      .
      .
      .
    ]
  }
}
 La risposta di esempio mostra come i dati seguono la forma della query. Ogni voce recuperata viene elencata nell'ambito del campo. peopleeoccupationsstanno restituendo le cose come elenchi separati. Sebbene utile, potrebbe essere più comodo modificare la query per restituire un elenco di nomi e occupazioni delle persone:
 query getItems {
   people {
      name   
      occupation {
        title
      }
}
 Questa è una modifica legale perché il nostro Persontipo contiene unoccupationcampo di tipoOccupation. Se elencati nell'ambito dipeople, restituiamo ciascunoPersondi essinameinsieme a quello associatoOccupationdatitle. La risposta potrebbe essere simile a questa:
 }
  "data": {
    "people": [
      {
        "name": "John Smith",
        "occupation": {
          "title": "Firefighter"
        }
      },
      {
        "name": "Andrew Miller",
        "occupation": {
          "title": "Bookkeeper"
        }
      },
      .
      .
      .
    ]
  }
}
 
- Mutations
- 
                        Le mutazioni sono simili a operazioni che cambiano lo stato come oPUT.POSTEseguono un'operazione di scrittura per modificare i dati nell'origine, quindi recuperano la risposta. Definiscono i punti di ingresso per le richieste di modifica dei dati. A differenza delle query, una mutazione può essere inclusa o meno nello schema a seconda delle esigenze del progetto. Ecco la mutazione dall'esempio dello schema:
 type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
 Il addPersoncampo rappresenta un punto di ingresso che aggiunge unPersonall'origine dati.addPersonè il nome del campo;id,name, eagesono i parametri; edPersonè il tipo restituito. Guardando indietro alPersontipo:
 type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
 Abbiamo aggiunto il occupationcampo. Tuttavia, non possiamo impostare questo campo suOccupationdirettamente perché gli oggetti non possono essere passati come argomenti; sono strettamente tipi di output. Dovremmo invece passare un input con gli stessi campi di un argomento:
 input occupationInput {
  title: String
}
  Possiamo anche aggiornare facilmente il nostro addPersonper includerlo come parametro quando creiamo nuovePersonistanze:
 type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
 Ecco lo schema aggiornato: type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
input occupationInput {
  title: String
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
 Nota che occupationpasserà neltitlecampo daoccupationInputper completare la creazione dell'oggettoPersonanziché dell'Occupationoggetto originale. Supponendo di avere un'implementazione del resolver peraddPerson, ora possiamo eseguire una mutazione effettiva. Sebbene ilMutationtipo esista, dobbiamo chiamarlo esplicitamente affinché venga eseguito nel codice dell'applicazione. Questo può essere fatto usando lamutationparola chiave:
 mutation createPerson {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput) {
    name
    age
    occupation {
      title
    }
  }
}
 Questa mutazione si chiamacreatePerson, edaddPersonè l'operazione. Per crearne una nuovaPerson, possiamo inserire gli argomenti perid,nameage, eoccupation. Nell'ambito diaddPerson, possiamo vedere anche altri campi comenameage, ecc. Questa è la tua risposta; questi sono i campi che verranno restituiti al termine dell'addPersonoperazione. Ecco la parte finale dell'esempio:
 mutation createPerson {
  addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner") {
    id
    name
    age
    occupation {
      title
    }
  }
}
 Utilizzando questa mutazione, un risultato potrebbe essere simile al seguente: {
  "data": {
    "addPerson": {
      "id": "1",
      "name": "Steve Powers",
      "age": "50",
      "occupation": {
        "title": "Miner"
      }
    }
  }
}
 Come puoi vedere, la risposta ha restituito i valori richiesti nello stesso formato definito nella nostra mutazione. È buona norma restituire tutti i valori che sono stati modificati per ridurre la confusione e la necessità di ulteriori query in futuro. Le mutazioni consentono di includere più operazioni nel suo ambito. Verranno eseguite in sequenza nell'ordine indicato nella mutazione. Ad esempio, se creiamo un'altra operazione chiamata addOccupationche aggiunge titoli di lavoro all'origine dati, possiamo richiamarla nella mutazione successiva.addPersonaddPersonverrà gestito per primo seguito da.addOccupation
 
- Subscriptions
- 
                        Gli abbonamenti vengono utilizzati WebSocketsper aprire una connessione bidirezionale duratura tra il server e i suoi client. In genere, un client si iscrive o ascolta il server. Ogni volta che il server apporta una modifica sul lato server o esegue un evento, il client sottoscritto riceverà gli aggiornamenti. Questo tipo di protocollo è utile quando sono sottoscritti più client e devono essere avvisati delle modifiche che avvengono nel server o in altri client. Ad esempio, gli abbonamenti possono essere utilizzati per aggiornare i feed dei social media. Potrebbero esserci due utenti, l'utente A e l'utente B, entrambi abbonati agli aggiornamenti automatici delle notifiche ogni volta che ricevono messaggi diretti. L'utente A sul client A potrebbe inviare un messaggio diretto all'utente B sul client B. Il client dell'utente A invierebbe il messaggio diretto, che verrebbe elaborato dal server. Il server invierebbe quindi il messaggio diretto all'account dell'utente B inviando una notifica automatica al client B. Ecco un esempio di a Subscriptionche potremmo aggiungere all'esempio dello schema:
 type Subscription {                                   
  personAdded: Person
}
 Il personAddedcampo invierà un messaggio ai clienti abbonati ogni volta che nePersonviene aggiunto uno nuovo alla fonte di dati. Supponendo di avere un'implementazione del resolver perpersonAdded, ora possiamo usare l'abbonamento. Sebbene ilSubscriptiontipo esista, dobbiamo chiamarlo esplicitamente affinché venga eseguito nel codice dell'applicazione. Questo può essere fatto usando lasubscriptionparola chiave:
 subscription personAddedOperation {
  personAdded {
    id
    name
  }
}
 L'abbonamento viene chiamato personAddedOperatione l'operazione èpersonAdded.personAddedrestituirà inamecampiide delle nuovePersonistanze. Guardando l'esempio di mutazione, abbiamo aggiunto un'operazione chePersonutilizza questa:
 addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner")
 Se i nostri clienti erano abbonati agli aggiornamenti di quelli appena aggiuntiPerson, potrebbero vederlo dopo l'addPersonesecuzione:
 {
  "data": {
    "personAdded": {
      "id": "1",
      "name": "Steve Powers"
    }
  }
}
 Di seguito è riportato un riepilogo di ciò che offrono gli abbonamenti: Gli abbonamenti sono canali bidirezionali che consentono al client e al server di ricevere aggiornamenti rapidi ma costanti. In genere utilizzano il  WebSocket  protocollo, che crea connessioni standardizzate e sicure. Gli abbonamenti sono agili in quanto riducono il sovraccarico di configurazione della connessione. Una volta sottoscritto, un cliente può continuare a utilizzare tale abbonamento per lunghi periodi di tempo. In genere utilizzano le risorse informatiche in modo efficiente, consentendo agli sviluppatori di personalizzare la durata dell'abbonamento e di configurare le informazioni richieste. In generale, gli abbonamenti consentono al cliente di effettuare più abbonamenti contemporaneamente. Per quanto riguarda AWS AppSync, gli abbonamenti vengono utilizzati solo per ricevere aggiornamenti in tempo reale dal servizio. AWS AppSync Non possono essere utilizzati per eseguire interrogazioni o mutazioni. L'alternativa principale agli abbonamenti è il polling, che invia interrogazioni a intervalli prestabiliti per richiedere dati. Questo processo è in genere meno efficiente degli abbonamenti e mette a dura prova sia il client che il backend. 
Una cosa che non è stata menzionata nel nostro esempio di schema è il fatto che anche i tipi di oggetti speciali devono essere definiti in una schema radice. Quindi, quando esporti uno schema in AWS AppSync, potrebbe assomigliare a questo:
               
                  - schema.graphql
- 
                        schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}
.
.
.
type Query {                                   
  # code goes here
}
type Mutation {                                   
  # code goes here
}
type Subscription {                                   
  # code goes here
}
 
Enumerazioni
               Le enumerazioni, o enumerazioni, sono scalari speciali che limitano gli argomenti legali di un tipo o di un campo. Ciò significa che ogni volta che un enum viene definito nello schema, il tipo o il campo associato sarà limitato ai valori nell'enum. Gli enum sono serializzati come stringhe scalari. Nota che diversi linguaggi di programmazione possono gestire le enumerazioni GraphQL in modo diverso. Ad esempio, non  JavaScript  ha un supporto enum nativo, quindi i valori enum possono essere mappati invece su valori int.
               Le enumerazioni vengono definite utilizzando la parola chiave. enum Ecco un esempio:
               enum trafficSignals {
  solidRed
  solidYellow
  solidGreen
  greenArrowLeft
  ...
}
               Quando si chiama l'trafficLightsenum, gli argomenti possono essere solosolidRed, solidYellowsolidGreen, ecc. È comune usare le enumerazioni per rappresentare cose che hanno un numero distinto ma limitato di scelte.
             
               Unioni/interfacce
               Vedi Interfacce e unioni in GraphQL.