

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Antarmuka dan serikat pekerja di GraphQL
<a name="interfaces-and-unions"></a>

[Sistem tipe GraphQL mendukung Antarmuka.](https://graphql.org/learn/schema/#interfaces) Antarmuka memperlihatkan sekumpulan bidang tertentu yang harus disertakan tipe untuk mengimplementasikan antarmuka. 

[Sistem tipe GraphQL juga mendukung Unions.](https://graphql.org/learn/schema/#union-types) Serikat pekerja identik dengan antarmuka, kecuali bahwa mereka tidak mendefinisikan sekumpulan bidang yang umum. Serikat pekerja umumnya lebih disukai daripada antarmuka ketika tipe yang mungkin tidak berbagi hierarki logis.

Bagian berikut adalah referensi untuk pengetikan skema.

## Contoh antarmuka
<a name="interfaces"></a>

Kami dapat mewakili `Event` antarmuka yang mewakili segala jenis aktivitas atau pengumpulan orang. Beberapa jenis acara yang mungkin adalah`Concert`,`Conference`, dan`Festival`. Semua jenis ini memiliki karakteristik umum, termasuk nama, tempat di mana acara berlangsung, dan tanggal mulai dan berakhir. Jenis ini juga memiliki perbedaan; a `Conference` menawarkan daftar pembicara dan lokakarya, sementara `Concert` fitur band pertunjukan.

Dalam Schema Definition Language (SDL), `Event` antarmuka didefinisikan sebagai berikut:

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

Dan masing-masing jenis mengimplementasikan `Event` antarmuka sebagai berikut:

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

Antarmuka berguna untuk mewakili elemen yang mungkin dari beberapa jenis. Misalnya, kami dapat mencari semua acara yang terjadi di tempat tertentu. Mari tambahkan `findEventsByVenue` bidang ke skema sebagai berikut:

```
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`Mengembalikan daftar`Event`. Karena bidang antarmuka GraphQL umum untuk semua jenis implementasi, dimungkinkan untuk memilih bidang apa pun pada `Event` antarmuka `id` (`name`,,,, `startsAt` `endsAt``venue`, dan). `minAgeRestriction` Selain itu, Anda dapat mengakses bidang pada jenis implementasi apa pun menggunakan fragmen [GraphQL](https://graphql.org/learn/queries/#fragments), selama Anda menentukan jenisnya.

Mari kita periksa contoh query GraphQL yang menggunakan antarmuka.

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

    ... on Festival {
      performers
    }

    ... on Concert {
      performingBand
    }

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

Kueri sebelumnya menghasilkan satu daftar hasil, dan server dapat mengurutkan peristiwa berdasarkan tanggal mulai secara default.

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

Karena hasil dikembalikan sebagai kumpulan peristiwa tunggal, menggunakan antarmuka untuk mewakili karakteristik umum sangat membantu untuk menyortir hasil.

## Contoh serikat
<a name="unions"></a>

Seperti yang dinyatakan sebelumnya, serikat pekerja tidak mendefinisikan kumpulan bidang umum. Hasil pencarian mungkin mewakili berbagai jenis. Dengan menggunakan `Event` skema, Anda dapat mendefinisikan `SearchResult` serikat sebagai berikut:

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

Dalam hal ini, untuk menanyakan bidang apa pun di `SearchResult` serikat kami, Anda harus menggunakan fragmen:

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

    ... on Festival {
      id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

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

## Ketik resolusi di AWS AppSync
<a name="type-resolution-in-appsynclong"></a>

Resolusi tipe adalah mekanisme dimana mesin GraphQL mengidentifikasi nilai yang diselesaikan sebagai jenis objek tertentu.

Kembali ke contoh pencarian serikat pekerja, asalkan kueri kami menghasilkan hasil, setiap item dalam daftar hasil harus menampilkan dirinya sebagai salah satu jenis yang mungkin yang didefinisikan oleh `SearchResult` serikat pekerja (yaitu,,, `Conference` `Festival``Concert`, atau`Venue`).

Karena logika untuk mengidentifikasi `Festival` dari a `Venue` atau a `Conference` tergantung pada persyaratan aplikasi, mesin GraphQL harus diberi petunjuk untuk mengidentifikasi kemungkinan jenis kami dari hasil mentah.

Dengan AWS AppSync, petunjuk ini diwakili oleh bidang meta bernama`__typename`, yang nilainya sesuai dengan nama jenis objek yang diidentifikasi. `__typename`diperlukan untuk tipe pengembalian yang merupakan antarmuka atau serikat pekerja.

## Contoh resolusi tipe
<a name="type-resolution-example"></a>

Mari kita gunakan kembali skema sebelumnya. Anda dapat mengikuti dengan menavigasi ke konsol dan menambahkan yang berikut di bawah halaman **Skema**:

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

Mari kita lampirkan resolver ke lapangan. `Query.search` Di `Resolvers` bagian ini, pilih **Lampirkan**, buat **Sumber Data** baru tipe *NONE*, lalu beri nama *StubDataSource*. Demi contoh ini, kita akan berpura-pura kita mengambil hasil dari sumber eksternal, dan kode keras hasil yang diambil dalam template pemetaan permintaan.

Di panel templat pemetaan permintaan, masukkan yang berikut ini:

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

Jika aplikasi mengembalikan nama tipe sebagai bagian dari `id` bidang, logika resolusi tipe harus mengurai `id` bidang untuk mengekstrak nama tipe dan kemudian menambahkan `__typename` bidang ke masing-masing hasil. Anda dapat melakukan logika itu di template pemetaan respons sebagai berikut:

**catatan**  
Anda juga dapat melakukan tugas ini sebagai bagian dari fungsi Lambda Anda, jika Anda menggunakan sumber data 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)
```

Jalankan kueri berikut:

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

    ... on Festival {
        id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

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

Kueri menghasilkan hasil sebagai berikut:

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

Logika resolusi tipe bervariasi tergantung pada aplikasi. Misalnya, Anda dapat memiliki logika pengenal yang berbeda yang memeriksa keberadaan bidang tertentu atau bahkan kombinasi bidang. Artinya, Anda dapat mendeteksi keberadaan `performers` bidang untuk mengidentifikasi `Festival` atau kombinasi dari `speakers` dan `workshops` bidang untuk mengidentifikasi a`Conference`. Pada akhirnya, terserah Anda untuk menentukan logika yang ingin Anda gunakan.