

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Referência de tipos do GraphQL
<a name="type-reference"></a>

Os tipos escalares no GraphQL representam valores de folha primitivos em um esquema do GraphQL. Esses são os tipos de dados mais básicos que são resolvidos como um único valor. Diferentemente dos tipos de objetos, os tipos escalares não podem ter subcampos. O GraphQL vem com um conjunto de tipos escalares padrão: 
+ **Int**: um inteiro assinado de 32 bits. 
+ **Float**: um valor de ponto flutuante de precisão dupla assinado. 
+ **String**: uma sequência de caracteres UTF-8. 
+ **Boolean**: um valor verdadeiro ou falso.
+ **ID**: um identificador exclusivo, geralmente usado para buscar novamente um objeto ou como a chave de um cache.

Esses tipos escalares servem como componentes básicos para tipos mais complexos em seu esquema. Eles são usados para definir campos que contêm valores simples e singulares. Além desses tipos escalares integrados, o AWS AppSync fornece tipos escalares adicionais para diferentes casos de uso. 

Interfaces e uniões no GraphQL são tipos abstratos que permitem um design de esquema flexível e extensível. Eles fornecem mecanismos para agrupar tipos relacionados e permitir consultas polimórficas. Uma interface no GraphQL é um tipo abstrato que define um conjunto de campos que um tipo deve incluir para implementar a interface. Ele serve como um contrato para objetos, especificando um conjunto comum de campos que os tipos de implementação devem ter. As interfaces são úteis quando você deseja retornar um objeto ou um campo que podem ser de vários tipos diferentes, mas ainda têm alguns campos garantidos. Por outro lado, uma união no GraphQL representa um tipo que pode ser um de vários tipos de objetos, mas não define nenhum campo comum entre esses tipos. As uniões são úteis quando você precisa retornar um campo que pode ser de vários tipos, e esses tipos não necessariamente compartilham campos comuns. Tanto as interfaces quanto as uniões são particularmente úteis em cenários em que um campo pode retornar diferentes tipos de dados, permitindo que os clientes consultem campos específicos com base no tipo retornado. 

Esta seção é usada como referência para tipos de esquema.

**Tópicos**
+ [Tipos escalares no GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html)
+ [Interfaces e uniões no GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html)

# Tipos escalares no GraphQL
<a name="scalars"></a>

Um tipo de objeto do GraphQL possui um nome e campos, e esses campos podem ter subcampos. Em última análise, os campos de um tipo de objeto devem ser resolvidos em tipos *escalares*, que representam as folhas da consulta. Para obter mais informações sobre tipos de objetos e escalares, consulte [Esquemas e tipos](https://graphql.org/learn/schema/) no site do GraphQL.

Além do conjunto padrão de escalares do GraphQL, o AWS AppSync também permite usar os escalares **definidos pelo serviço** que começam com o prefixo *AWS*. O AWS AppSync não oferece suporte à criação de escalares definidos pelo usuário (personalizados). Você deve usar o padrão ou escalares da *AWS*. 

Você não pode usar *AWS* como prefixo para tipos de objetos personalizados.

A seção a seguir é uma referência para digitação de esquema.

## Escalares padrão
<a name="graph-ql-base-scalars"></a>

O GraphQL define os seguintes escalares padrão:

### Lista de escalares padrão
<a name="graph-ql-base-scalars-list"></a>

`ID`  
Um identificador exclusivo para um objeto. Este escalar é serializado como `String`, mas não foi feito para ser legível por humanos.

`String`  
Uma sequência de caracteres UTF-8.

`Int`  
Um valor inteiro entre -(231) e 231-1.

`Float`  
Um valor de ponto flutuante IEEE 754.

`Boolean`  
Um valor booliano, `true` ou `false`.

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

AWS AppSync define os seguintes escalares:

### Lista escalares de AWS AppSync
<a name="graph-ql-aws-appsync-scalars-list"></a>

`AWSDate`  
Uma string de [data ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) estendida no formato `YYYY-MM-DD`.

`AWSTime`  
Uma string de [horário ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times) estendida no formato `hh:mm:ss.sss`.

`AWSDateTime`  
Uma string de [data e horário ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) estendida no formato `YYYY-MM-DDThh:mm:ss.sssZ`.

**nota**  
Os escalares `AWSDate`, `AWSTime` e `AWSDateTime` podem incluir um [deslocamento de fuso horário](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators). Por exemplo, os valores `1970-01-01Z`, `1970-01-01-07:00` e `1970-01-01+05:30` são todos válidos para `AWSDate`. O deslocamento do fuso horário deve ser `Z` (UTC) ou um deslocamento em horas e minutos (e, opcionalmente, segundos). Por exemplo, `±hh:mm:ss`. O campo de segundos no deslocamento de fuso horário é considerado válido mesmo que não faça parte do padrão ISO 8601.

`AWSTimestamp`  
Um valor inteiro que representa o número de segundos antes ou depois de `1970-01-01-T00:00Z`.

`AWSEmail`  
Um endereço de email no formato `local-part@domain-part` definido pela [RFC 822](https://tools.ietf.org/html/rfc822).

`AWSJSON`  
Uma string JSON. Qualquer estrutura JSON válida é automaticamente analisada e carregada no código do resolvedor como mapas, listas ou valores escalares, em vez de strings de entrada literais. Strings sem aspas ou JSON inválido resultam em um erro de validação do GraphQL.​

`AWSPhone`  
Um número de telefone. Esse valor é armazenado como uma string. Os números de telefone podem conter espaços ou hífens para separar grupos de dígitos. Os números de telefone sem código de país são considerados números dos EUA/norte-americanos que aderem ao [Plano de Numeração norte-americano (NANP)](https://en.wikipedia.org/wiki/North_American_Numbering_Plan).

`AWSURL`  
Um URL conforme definido pela [RFC 1738](https://tools.ietf.org/html/rfc1738). Por exemplo, `https://www.amazon.com/dp/B000NZW3KC/` ou `mailto:example@example.com`. Os URLs devem conter um esquema (`http`, `mailto`) e não podem conter duas barras (`//`) na parte do caminho.

`AWSIPAddress`  
Um endereço IPv4 ou IPv6 válido. Os endereços IPv4 são esperados em notação com quatro pontos (`123.12.34.56`). Os endereços IPv6 são esperados em formato sem colchetes e separados por dois pontos (`1a2b:3c4b::1234:4567`). Você pode incluir um sufixo CIDR opcional (`123.45.67.89/16`) para indicar a máscara de sub-rede.

## Exemplo de uso de esquema
<a name="example-schema-usage"></a>

O exemplo de esquema do GraphQL a seguir usa todos os escalares personalizados como um "objeto" e mostra os modelos de solicitação e resposta do resolvedor para operações básicas de colocação, obtenção e lista. Por fim, o exemplo mostra como você pode usar isso ao executar consultas e mutações.

```
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
}
```

Esta é a aparência de um modelo de solicitação para `putObject`. Um `putObject` usa uma operação `PutItem` para criar ou atualizar um item na tabela do Amazon DynamoDB. Observe que esse trecho de código não tem uma tabela do Amazon DynamoDB configurada como fonte de dados. Ele está sendo usado apenas como exemplo:

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

O modelo de resposta para `putObject` retorna os resultados:

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

Esta é a aparência de um modelo de solicitação para `getObject`. Um `getObject` usa uma operação `GetItem` para retornar um conjunto de atributos para o item dada a chave primária. Observe que esse trecho de código não tem uma tabela do Amazon DynamoDB configurada como fonte de dados. Ele está sendo usado apenas como exemplo:

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

O modelo de resposta para `getObject` retorna os resultados:

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

Esta é a aparência de um modelo de solicitação para `listObjects`. Um `listObjects` usa uma operação `Scan` para retornar um ou mais itens e atributos. Observe que esse trecho de código não tem uma tabela do Amazon DynamoDB configurada como fonte de dados. Ele está sendo usado apenas como exemplo:

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

O modelo de resposta para `listObjects` retorna os resultados:

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

Veja a seguir alguns exemplos de uso deste esquema com consultas do 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
    }
}
```

# Interfaces e uniões no GraphQL
<a name="interfaces-and-unions"></a>

O sistema do tipo GraphQL oferece suporte a [interfaces](https://graphql.org/learn/schema/#interfaces). Uma interface expõe um determinado conjunto de campos que um tipo deve incluir para implementar a interface. 

O sistema de tipos GraphQL também oferece suporte a [Uniões](https://graphql.org/learn/schema/#union-types). As uniões são idênticas às interfaces, exceto que não definem um conjunto comum de campos. As uniões geralmente são preferidas em relação às interfaces quando os tipos possíveis não compartilham uma hierarquia lógica.

A seção a seguir é uma referência para digitação de esquema.

## Exemplos de interface
<a name="interfaces"></a>

Podemos representar uma interface `Event` que representa qualquer tipo de atividade ou reunião de pessoas. Alguns tipos de eventos possíveis são `Concert`, `Conference` e `Festival`. Esses tipos possuem características em comum, incluindo um nome, um local onde o evento está acontecendo e datas de início e término. Esses tipos também têm diferenças, uma `Conference` oferece uma lista de palestrantes e seminários enquanto um `Concert` contém uma banda em apresentação.

No SDL (Schema Definition Language), a interface `Event` é definida da seguinte forma:

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

E cada um dos tipos implementa a interface `Event` da seguinte forma:

```
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]
}
```

As interfaces são úteis para representar elementos que podem ser de vários tipos. Por exemplo, podemos pesquisar todos os eventos que acontecem em um local específico. Vamos adicionar um campo `findEventsByVenue` ao esquema da seguinte forma:

```
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]
}
```

O `findEventsByVenue` retorna uma lista de `Event`. Como os campos da interface do GraphQL são comuns a todos os tipos de implementação, é possível selecionar qualquer campo na interface `Event` (`id`, `name`, `startsAt`, `endsAt`, `venue` e `minAgeRestriction`). Além disso, é possível acessar os campos em qualquer tipo de implementação usando [fragmentos](https://graphql.org/learn/queries/#fragments) do GraphQL, desde que o tipo seja especificado.

Vamos examinar um exemplo de uma consulta do GraphQL que usa a interface.

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

    ... on Festival {
      performers
    }

    ... on Concert {
      performingBand
    }

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

A consulta anterior produz uma única lista de resultados e o servidor pode, por padrão, classificar os eventos por data de início.

```
{
  "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"
        ]
      }
    ]
  }
}
```

Como os resultados são retornados como uma única coleção de eventos, o uso de interfaces para representar características comuns é muito útil para classificar os resultados.

## Exemplos de uniões
<a name="unions"></a>

Conforme mencionado anteriormente, as uniões não definem conjuntos comuns de campos. Um resultado de pesquisa pode representar muitos tipos diferentes. Usando o esquema `Event`, defina uma união `SearchResult` da seguinte forma:

```
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
```

Neste caso, para consultar qualquer campo na nossa união `SearchResult`, deve-se usar fragmentos.

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

    ... on Festival {
      id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

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

## Resolução de texto em AWS AppSync
<a name="type-resolution-in-appsynclong"></a>

A resolução de tipo é o mecanismo pelo qual o mecanismo do GraphQL identifica um valor resolvido como um tipo de objeto específico.

Voltando ao exemplo de pesquisa da união, assumindo que a consulta gerou resultados, cada item na lista de resultados deve se apresentar como um dos tipos possíveis definidos pela união `SearchResult` (isto é, `Conference`, `Festival`, `Concert` ou `Venue`).

Como a lógica para identificar um `Festival` de uma `Venue` ou uma `Conference` depende dos requisitos do aplicativo, o mecanismo do GraphQL deve receber uma dica para identificar os tipos possíveis nos resultados brutos.

Com AWS AppSync, essa dica é representada por um metacampo chamado`__typename`, cujo valor corresponde ao nome do tipo de objeto identificado. `__typename`é necessário para tipos de retorno que sejam interfaces ou uniões.

## Exemplo de resolução de tipo
<a name="type-resolution-example"></a>

Vamos reutilizar o esquema anterior. Você pode acompanhar navegando até o console e adicionando o seguinte na página **Esquema**:

```
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
}
```

Vamos anexar um resolvedor ao campo `Query.search`. Na `Resolvers` seção, escolha **Anexar**, crie uma nova **fonte de dados** do tipo *NENHUMA* e, em seguida, nomeie-a *StubDataSource*. Para esse exemplo, vamos imaginar que os resultados foram obtidos de uma fonte externa e codificar os resultados no modelo de mapeamento da solicitação.

No painel do modelo de mapeamento da solicitação, insira o seguinte:

```
{
    "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 o aplicativo retornar o nome do tipo como parte do campo`id`, a lógica de resolução de tipo deverá analisar o campo `id` para extrair o nome do tipo e, em seguida, adicionar o campo `__typename` a cada um dos resultados. Você pode executar essa lógica no modelo de mapeamento da resposta da seguinte forma:

**nota**  
Observação: também é possível executar essa tarefa como parte da função do Lambda se você estiver usando a fonte de dados do 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)
```

Execute a seguinte consulta:

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

    ... on Festival {
        id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

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

A consulta gera os seguintes resultados:

```
{
  "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"
        ]
      }
    ]
  }
}
```

A lógica da resolução de tipo varia dependendo do aplicativo. Por exemplo, você pode ter uma lógica de identificação diferente que verifica a existência de determinados campos ou até mesmo uma combinação de campos. Ou seja, é possível detectar a presença do campo `performers` para identificar um `Festival` ou a combinação dos `speakers` e dos campos `workshops` para identificar uma `Conference`. De forma geral, cabe a você definir a lógica que deseja usar.