

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à.

# Riferimento al tipo GraphQL
<a name="type-reference"></a>

I tipi scalari in GraphQL rappresentano valori leaf primitivi in uno schema GraphQL. Questi sono i tipi di dati più basilari che si risolvono in un unico valore. A differenza dei tipi di oggetti, i tipi scalari non possono avere sottocampi. GraphQL viene fornito con un set di tipi scalari predefiniti: 
+ **Int**: un numero intero con segno a 32 bit 
+ **Float**: un valore a virgola mobile con segno a doppia precisione 
+ String: **una sequenza di caratteri UTF-8** 
+ **Boolean: un valore vero o** falso
+ **ID**: un identificatore univoco, spesso usato per recuperare un oggetto o come chiave per una cache

Questi tipi scalari fungono da elementi costitutivi per i tipi più complessi dello schema. Vengono utilizzati per definire campi che contengono valori semplici e singolari. Oltre a questi scalari integrati, AWS AppSync fornisce scalari aggiuntivi per diversi casi d'uso. 

Le interfacce e le unioni in GraphQL sono tipi astratti che consentono una progettazione di schemi flessibile ed estensibile. Forniscono meccanismi per raggruppare i tipi correlati e abilitare le query polimorfe. Un'interfaccia in GraphQL è un tipo astratto che definisce un insieme di campi che un tipo deve includere per implementare l'interfaccia. Funge da contratto per gli oggetti specificando un insieme comune di campi che i tipi di implementazione devono avere. Le interfacce sono utili quando si desidera restituire un oggetto o un campo che può essere di diversi tipi, ma che ha comunque alcuni campi garantiti. Al contrario, un Union in GraphQL rappresenta un tipo che potrebbe essere uno dei diversi tipi di oggetto, ma non definisce alcun campo comune tra questi tipi. Le unioni sono utili quando è necessario restituire un campo che può essere di più tipi e questi tipi non condividono necessariamente campi comuni. Sia le interfacce che le unioni sono particolarmente utili negli scenari in cui un campo può restituire diversi tipi di dati, consentendo ai client di eseguire query per campi specifici in base al tipo restituito. 

Questa sezione viene utilizzata come riferimento per i tipi di schema.

**Argomenti**
+ [Tipi scalari in GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html)
+ [Interfacce e unioni in GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html)

# Tipi scalari in GraphQL
<a name="scalars"></a>

Un tipo di oggetto GraphQL ha un nome e campi e tali campi possono avere sottocampi. In definitiva, i campi di un tipo di oggetto devono risolversi in tipi *scalari*, che rappresentano i fogli della query. Per ulteriori informazioni sui tipi di oggetti e sugli scalari, consulta [Schemi e tipi sul sito](https://graphql.org/learn/schema/) Web GraphQL.

Oltre al set predefinito di scalari GraphQL, consente AWS AppSync anche di utilizzare gli scalari **definiti dal servizio che iniziano con** il prefisso. *AWS* AWS AppSync **non supporta la creazione di scalari definiti dall'utente (personalizzati).** È necessario utilizzare gli scalari predefiniti o *AWS*quelli scalari. 

Non è possibile utilizzare *AWS*come prefisso per tipi di oggetti personalizzati.

La sezione seguente è un riferimento per la digitazione dello schema.

## Scalari predefiniti
<a name="graph-ql-base-scalars"></a>

GraphQL definisce i seguenti scalari predefiniti:

### Elenco degli scalari predefiniti
<a name="graph-ql-base-scalars-list"></a>

`ID`  
Un identificatore univoco per un oggetto. Questo scalare è serializzato come un `String` ma non è pensato per essere leggibile dall'uomo.

`String`  
Una sequenza di caratteri UTF-8.

`Int`  
Un valore intero compreso tra - (2 31) e 2 31 -1.

`Float`  
Un valore in virgola mobile IEEE 754.

`Boolean`  
Un valore booleano, `true` o `false`.

## AWS AppSync scalari
<a name="graph-ql-aws-appsync-scalars"></a>

AWS AppSync definisce i seguenti scalari:

### AWS AppSync elenco degli scalari
<a name="graph-ql-aws-appsync-scalars-list"></a>

`AWSDate`  
Una stringa di [data ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) estesa nel formato. `YYYY-MM-DD`

`AWSTime`  
Una stringa [temporale ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times) estesa nel formato. `hh:mm:ss.sss`

`AWSDateTime`  
Una stringa estesa di [data e ora ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) nel formato. `YYYY-MM-DDThh:mm:ss.sssZ`

**Nota**  
Gli `AWSDateTime` scalari `AWSDate``AWSTime`, e possono facoltativamente includere un offset del fuso [orario.](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators) Ad esempio, i valori `1970-01-01Z``1970-01-01-07:00`, e `1970-01-01+05:30` sono tutti validi per. `AWSDate` L'offset del fuso orario deve essere `Z` (UTC) o un offset in ore e minuti (e, facoltativamente, secondi). Ad esempio `±hh:mm:ss`. Il campo dei secondi nell'offset del fuso orario è considerato valido anche se non fa parte dello standard ISO 8601.

`AWSTimestamp`  
Un valore intero che rappresenta il numero di secondi prima o dopo. `1970-01-01-T00:00Z`

`AWSEmail`  
Un indirizzo e-mail nel formato `local-part@domain-part` definito da [RFC](https://tools.ietf.org/html/rfc822) 822.

`AWSJSON`  
Una stringa JSON. Qualsiasi costrutto JSON valido viene automaticamente analizzato e caricato nel codice del resolver come mappe, elenchi o valori scalari anziché come stringhe di input letterali. Le stringhe senza virgolette o il codice JSON altrimenti non valido generano un errore di convalida GraphQL.

`AWSPhone`  
Un numero di telefono. Questo valore viene memorizzato come stringa. I numeri di telefono possono contenere spazi o trattini per separare gruppi di cifre. Si presume che i numeri di telefono senza prefisso internazionale siano numeri statunitensi o nordamericani che aderiscono al North American Numbering Plan ([NANP](https://en.wikipedia.org/wiki/North_American_Numbering_Plan)).

`AWSURL`  
[Un URL come definito da RFC 1738.](https://tools.ietf.org/html/rfc1738) Ad esempio, `https://www.amazon.com/dp/B000NZW3KC/` o. `mailto:example@example.com` URLsdeve contenere uno schema (`http`,`mailto`) e non può contenere due barre (`//`) nella parte del percorso.

`AWSIPAddress`  
Un IPv6 indirizzo IPv4 o valido. IPv4 gli indirizzi sono previsti in notazione quadrupla (). `123.12.34.56` IPv6 gli indirizzi sono previsti in formato non tra parentesi e separati da due punti (). `1a2b:3c4b::1234:4567` È possibile includere un suffisso CIDR opzionale () `123.45.67.89/16` per indicare la subnet mask.

## Esempio di utilizzo dello schema
<a name="example-schema-usage"></a>

Lo schema GraphQL di esempio seguente utilizza tutti gli scalari personalizzati come «oggetto» e mostra i modelli di richiesta e risposta del resolver per le operazioni di base di put, get e list. Infine, l'esempio mostra come è possibile utilizzarlo durante l'esecuzione di query e mutazioni.

```
type Mutation {
    putObject(
        email: AWSEmail,
        json: AWSJSON,
        date: AWSDate,
        time: AWSTime,
        datetime: AWSDateTime,
        timestamp: AWSTimestamp,
        url: AWSURL,
        phoneno: AWSPhone,
        ip: AWSIPAddress
    ): Object
}

type Object {
    id: ID!
    email: AWSEmail
    json: AWSJSON
    date: AWSDate
    time: AWSTime
    datetime: AWSDateTime
    timestamp: AWSTimestamp
    url: AWSURL
    phoneno: AWSPhone
    ip: AWSIPAddress
}

type Query {
    getObject(id: ID!): Object
    listObjects: [Object]
}

schema {
    query: Query
    mutation: Mutation
}
```

Ecco come `putObject` potrebbe apparire un modello di richiesta. A `putObject` utilizza un'`PutItem`operazione per creare o aggiornare un elemento nella tabella Amazon DynamoDB. Tieni presente che questo frammento di codice non ha una tabella Amazon DynamoDB configurata come origine dati. Questo viene usato solo come esempio:

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

Il modello di risposta per `putObject` restituisce i risultati:

```
$util.toJson($ctx.result)
```

Ecco come `getObject` potrebbe apparire un modello di richiesta. A `getObject` utilizza un'`GetItem`operazione per restituire un insieme di attributi per l'elemento a cui è stata assegnata la chiave primaria. Tieni presente che questo frammento di codice non ha una tabella Amazon DynamoDB configurata come origine dati. Questo viene usato solo come esempio:

```
{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

Il modello di risposta per `getObject` restituisce i risultati:

```
$util.toJson($ctx.result)
```

Ecco come `listObjects` potrebbe apparire un modello di richiesta. A `listObjects` utilizza un'`Scan`operazione per restituire uno o più elementi e attributi. Tieni presente che questo frammento di codice non ha una tabella Amazon DynamoDB configurata come origine dati. Questo viene usato solo come esempio:

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
}
```

Il modello di risposta per `listObjects` restituisce i risultati:

```
$util.toJson($ctx.result.items)
```

Di seguito sono riportati alcuni esempi di utilizzo di questo schema con le query GraphQL:

```
mutation CreateObject {
    putObject(email: "example@example.com"
        json: "{\"a\":1, \"b\":3, \"string\": 234}"
        date: "1970-01-01Z"
        time: "12:00:34."
        datetime: "1930-01-01T16:00:00-07:00"
        timestamp: -123123
        url:"https://amazon.com"
        phoneno: "+1 555 764 4377"
        ip: "127.0.0.1/8"
    ) {
        id
        email
        json
        date
        time
        datetime
        url
        timestamp
        phoneno
        ip
    }
}

query getObject {
    getObject(id:"0d97daf0-48e6-4ffc-8d48-0537e8a843d2"){
        email
        url
        timestamp
        phoneno
        ip
    }
}

query listObjects {
    listObjects {
        json
        date
        time
        datetime
    }
}
```

# Interfacce e unioni in GraphQL
<a name="interfaces-and-unions"></a>

[Il sistema di tipo GraphQL supporta le interfacce.](https://graphql.org/learn/schema/#interfaces) Un'interfaccia espone un determinato set di campi che deve essere incluso in un tipo per implementare l'interfaccia. 

[Il sistema di tipo GraphQL supporta anche Unions.](https://graphql.org/learn/schema/#union-types) Le unioni sono identiche alle interfacce, ad eccezione del fatto che non definiscono un set comune di campi. Le unioni sono in genere preferibili rispetto alle interfacce quando i tipi possibili non condividono una gerarchia logica.

La sezione seguente è un riferimento per la digitazione dello schema.

## Esempi di interfacce
<a name="interfaces"></a>

Potremmo rappresentare un'`Event`interfaccia che rappresenta qualsiasi tipo di attività o incontro di persone. Alcuni tipi di eventi possibili sono `Concert``Conference`, e`Festival`. Questi tipi condividono tutti caratteristiche comuni, in quanto hanno tutti un nome, un luogo in cui avviene l'evento e una data di inizio e una di fine. Anche questi tipi presentano delle differenze; a `Conference` offre un elenco di relatori e workshop, mentre a `Concert` presenta una band che si esibisce.

In Schema Definition Language (SDL), l'`Event`interfaccia è definita come segue:

```
interface Event {
        id: ID!
        name : String!
        startsAt: String
        endsAt: String
        venue: Venue
        minAgeRestriction: Int
}
```

E ciascuno dei tipi implementa l'`Event`interfaccia come segue:

```
type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

Le interfacce sono utili per rappresentare elementi che possono essere di diversi tipi. Ad esempio, possiamo cercare tutti gli eventi che avvengono in un luogo specifico. Aggiungiamo un campo `findEventsByVenue` allo schema come segue:

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
}

type Venue {
    id: ID!
    name: String
    address: String
    maxOccupancy: Int
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

`findEventsByVenue`Restituisce un elenco di. `Event` Poiché i campi dell'interfaccia GraphQL sono comuni a tutti i tipi di implementazione, è possibile selezionare qualsiasi campo nell'interfaccia `Event` (`id`, `name`, `startsAt`, `endsAt`, `venue` e `minAgeRestriction`). Inoltre, puoi accedere ai campi in qualsiasi tipo di implementazione utilizzando [frammenti](https://graphql.org/learn/queries/#fragments) GraphQL, purché specifichi il tipo.

Esaminiamo un esempio di query GraphQL che utilizza l'interfaccia.

```
query {
  findEventsAtVenue(venueId: "Madison Square Garden") {
    id
    name
    minAgeRestriction
    startsAt

    ... on Festival {
      performers
    }

    ... on Concert {
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

La query precedente produce un singolo elenco di risultati e il server può, per impostazione predefinita, ordinare gli eventi in base alla data di inizio.

```
{
  "data": {
    "findEventsAtVenue": [
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "minAgeRestriction": 21,
        "startsAt": "2018-10-05T14:48:00.000Z",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "minAgeRestriction": 18,
        "startsAt": "2018-10-07T14:48:00.000Z",
        "performingBand": "The Jumpers"
      },
      {
        "id": "Conference-4",
        "name": "Conference 4",
        "minAgeRestriction": null,
        "startsAt": "2018-10-09T14:48:00.000Z",
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

Poiché i risultati vengono restituiti come una singola raccolta di eventi, l'utilizzo di interfacce per rappresentare caratteristiche comuni è molto utile per l'ordinamento dei risultati.

## Esempi di unione
<a name="unions"></a>

Come affermato in precedenza, i sindacati non definiscono insiemi di campi comuni. Un risultato di ricerca potrebbe rappresentare molti tipi diversi. Utilizzando lo schema `Event`, è possibile definire un'unione `SearchResult` come segue:

```
type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue
```

In questo caso, per interrogare qualsiasi campo sulla nostra `SearchResult` unione, devi usare i frammenti:

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
      id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

## Digita la risoluzione in AWS AppSync
<a name="type-resolution-in-appsynclong"></a>

La risoluzione dei tipi è il meccanismo attraverso il quale il motore GraphQL identifica un valore risolto come tipo di oggetto specifico.

Tornando all'esempio della ricerca sindacale, a condizione che la nostra query abbia prodotto risultati, ogni elemento nell'elenco dei risultati deve presentarsi come uno dei possibili tipi definiti dall'`SearchResult`unione (ovvero,, `Conference` `Festival``Concert`, o`Venue`).

Poiché la logica per identificare un tipo `Festival` rispetto a un tipo `Venue` o `Conference` dipende dai requisiti dell'applicazione, il motore GraphQL deve ricevere un suggerimento per identificare i possibili tipi dai risultati non elaborati.

Con AWS AppSync, questo suggerimento è rappresentato da un metacampo denominato`__typename`, il cui valore corrisponde al nome del tipo di oggetto identificato. `__typename`è obbligatorio per i tipi restituiti che sono interfacce o unioni.

## Esempio di risoluzione dei tipi
<a name="type-resolution-example"></a>

Ora, riutilizzeremo lo schema precedente. Puoi continuare passando alla console e aggiungendo il codice seguente nella pagina **Schema**:

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue

type Venue {
    id: ID!
    name: String!
    address: String
    maxOccupancy: Int
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}
```

Colleghiamo un resolver al campo `Query.search`. Nella `Resolvers` sezione, scegliete **Allega**, create una nuova **origine dati** di tipo *NONE*, quindi assegnatele un nome *StubDataSource*. Ai fini di questo esempio, fingeremo di aver recuperato i risultati da un'origine esterna e di aver codificato tali risultati nel modello di mappatura della richiesta.

Nel riquadro del modello di mappatura della richiesta immetti i seguenti dati:

```
{
    "version" : "2018-05-29",
    "payload":
    ## We are effectively mocking our search results for this example
    [
        {
            "id": "Venue-1",
            "name": "Venue 1",
            "address": "2121 7th Ave, Seattle, WA 98121",
            "maxOccupancy": 1000
        },
        {
            "id": "Festival-2",
            "name": "Festival 2",
            "performers": ["The Singers", "The Screamers"]
        },
        {
            "id": "Concert-3",
            "name": "Concert 3",
            "performingBand": "The Jumpers"
        },
        {
            "id": "Conference-4",
            "name": "Conference 4",
            "speakers": ["The Storytellers"],
            "workshops": ["Writing", "Reading"]
        }
    ]
}
```

Se l'applicazione restituisce il nome del tipo come parte del `id` campo, la logica di risoluzione dei tipi deve analizzare il `id` campo per estrarre il nome del tipo e quindi aggiungere il `__typename` campo a ciascuno dei risultati. È possibile eseguire la logica nel modello di mappatura della risposta come segue:

**Nota**  
Puoi eseguire questa attività anche come parte della tua funzione Lambda, se utilizzi l'origine dati Lambda.

```
#foreach ($result in $context.result)
    ## Extract type name from the id field.
    #set( $typeName = $result.id.split("-")[0] )
    #set( $ignore = $result.put("__typename", $typeName))
#end
$util.toJson($context.result)
```

Eseguire la seguente query:

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
        id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

La query restituisce i seguenti risultati:

```
{
  "data": {
    "search": [
      {
        "id": "Venue-1",
        "name": "Venue 1",
        "address": "2121 7th Ave, Seattle, WA 98121"
      },
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "performingBand": "The Jumpers"
      },
      {
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

La logica di risoluzione dei tipi varia a seconda dell'applicazione. Ad esempio, puoi definire una logica di identificazione diversa che controlla l'esistenza di determinati campi o addirittura una combinazione di campi. Ovvero, puoi rilevare la presenza del campo `performers` per identificare un tipo `Festival` o la combinazione dei campi `speakers` e `workshops` per identificare un tipo `Conference`. In definitiva, sta a te definire la logica che desideri utilizzare.