

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

# GraphQL skema
<a name="schema-components"></a>

Skema GraphQL adalah dasar dari GraphQL API. Ini berfungsi sebagai cetak biru yang mendefinisikan bentuk data Anda. Ini juga merupakan kontrak antara klien dan server Anda yang menentukan bagaimana data Anda akan diambil dimodifikasi and/or .

Skema GraphQL ditulis dalam Schema Definition Language (*SDL*). SDL terdiri dari jenis dan bidang dengan struktur yang mapan:
+ **Jenis**: Jenis adalah bagaimana GraphQL mendefinisikan bentuk dan perilaku data. GraphQL mendukung banyak jenis yang akan dijelaskan nanti di bagian ini. Setiap jenis yang didefinisikan dalam skema Anda akan berisi cakupannya sendiri. Di dalam ruang lingkup akan ada satu atau lebih bidang yang dapat berisi nilai atau logika yang akan digunakan dalam layanan GraphQL Anda. Jenis mengisi banyak peran yang berbeda, yang paling umum adalah objek atau skalar (tipe nilai primitif).
+ **Bidang**: Bidang ada dalam lingkup tipe dan menyimpan nilai yang diminta dari layanan GraphQL. Ini sangat mirip dengan variabel dalam bahasa pemrograman lain. Bentuk data yang Anda tentukan di bidang Anda akan menentukan bagaimana data terstruktur dalam suatu request/response operasi. Hal ini memungkinkan pengembang untuk memprediksi apa yang akan dikembalikan tanpa mengetahui bagaimana backend layanan diimplementasikan.

Untuk memvisualisasikan seperti apa skema, mari kita tinjau isi skema GraphQL sederhana. Dalam kode produksi, skema Anda biasanya akan berada dalam file bernama `schema.graphql` atau`schema.json`. Mari kita asumsikan bahwa kita mengintip ke dalam proyek yang mengimplementasikan layanan GraphQL. Proyek ini menyimpan data personel perusahaan, dan `schema.graphql` file tersebut digunakan untuk mengambil data personel dan menambahkan personel baru ke database. Kode mungkin terlihat seperti ini:

------
#### [ schema.graphql ]

```
type Person {                                  
   id: ID!
   name: String                                  
   age: Int
}
type Query {                                   
  people: [Person]
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
```

------

Kita dapat melihat bahwa ada tiga jenis yang didefinisikan dalam skema:`Person`,`Query`, dan`Mutation`. Melihat`Person`, kita dapat menebak bahwa ini adalah cetak biru untuk contoh karyawan perusahaan, yang akan membuat tipe ini menjadi objek. Di dalam ruang lingkupnya, kita lihat`id`,`name`, dan`age`. Ini adalah bidang yang menentukan properti dari a`Person`. Ini berarti sumber data kami menyimpan masing-masing `Person` `name` sebagai tipe `String` skalar (primitif) dan `age` sebagai tipe `Int` skalar (primitif). `id`Bertindak sebagai pengenal khusus dan unik untuk masing-masing`Person`. Ini juga merupakan nilai yang diperlukan seperti yang dilambangkan dengan simbol. `!`

Dua tipe objek berikutnya berperilaku berbeda. GraphQL menyimpan beberapa kata kunci untuk jenis objek khusus yang menentukan bagaimana data akan diisi dalam skema. `Query`Tipe akan mengambil data dari sumbernya. Dalam contoh kita, query kita mungkin mengambil `Person` objek dari database. Ini mungkin mengingatkan Anda tentang `GET` operasi dalam RESTful terminologi. A `Mutation` akan memodifikasi data. Dalam contoh kita, mutasi kita dapat menambahkan lebih banyak `Person` objek ke database. Ini mungkin mengingatkan Anda tentang operasi yang mengubah negara seperti `PUT` atau. `POST` Perilaku semua jenis objek khusus akan dijelaskan nanti di bagian ini.

Mari kita asumsikan `Query` dalam contoh kita akan mengambil sesuatu dari database. Jika kita melihat bidang`Query`, kita melihat satu bidang yang disebut`people`. Nilai bidangnya adalah`[Person]`. Ini berarti kita ingin mengambil beberapa contoh dari `Person` dalam database. Namun, penambahan tanda kurung berarti bahwa kita ingin mengembalikan daftar semua `Person` instance dan bukan hanya yang spesifik.

`Mutation`Tipe ini bertanggung jawab untuk melakukan operasi perubahan status seperti modifikasi data. Mutasi bertanggung jawab untuk melakukan beberapa operasi perubahan keadaan pada sumber data. Dalam contoh kita, mutasi kita berisi operasi yang disebut `addPerson` yang menambahkan `Person` objek baru ke database. Mutasi menggunakan a `Person` dan mengharapkan input untuk`id`,`name`, dan `age` bidang.

Pada titik ini, Anda mungkin bertanya-tanya bagaimana operasi seperti `addPerson` bekerja tanpa implementasi kode mengingat bahwa itu seharusnya melakukan beberapa perilaku dan terlihat sangat mirip fungsi dengan nama fungsi dan parameter. Saat ini, itu tidak akan berfungsi karena skema hanya berfungsi sebagai deklarasi. Untuk mengimplementasikan perilaku`addPerson`, kita harus menambahkan resolver ke dalamnya. Resolver adalah unit kode yang dieksekusi setiap kali bidang terkait (dalam hal ini, `addPerson` operasi) dipanggil. Jika Anda ingin menggunakan operasi, Anda harus menambahkan implementasi resolver di beberapa titik. Di satu sisi, Anda dapat menganggap operasi skema sebagai deklarasi fungsi dan resolver sebagai definisi. Resolver akan dijelaskan di bagian yang berbeda.

Contoh ini hanya menunjukkan cara paling sederhana skema dapat memanipulasi data. Anda membangun aplikasi yang kompleks, kuat, dan dapat diskalakan dengan memanfaatkan fitur GraphQL dan. AWS AppSync Di bagian selanjutnya, kita akan mendefinisikan semua jenis dan perilaku lapangan yang berbeda yang dapat Anda manfaatkan dalam skema Anda.

# Jenis GraphQL
<a name="graphql-types"></a>

GraphQL mendukung berbagai jenis. Seperti yang Anda lihat di bagian sebelumnya, tipe menentukan bentuk atau perilaku data Anda. Mereka adalah blok bangunan mendasar dari skema GraphQL. 

Jenis dapat dikategorikan ke dalam input dan output. Input adalah tipe yang diizinkan untuk diteruskan sebagai argumen untuk tipe objek khusus (`Query`,, dll.)`Mutation`, sedangkan tipe output secara ketat digunakan untuk menyimpan dan mengembalikan data. Daftar jenis dan kategorisasi mereka tercantum di bawah ini:
+ **Objek**: Objek berisi bidang yang menggambarkan entitas. Misalnya, objek bisa berupa sesuatu seperti a `book` dengan bidang yang menggambarkan karakteristiknya seperti`authorName`,`publishingYear`, dll. Mereka benar-benar tipe output.
+ **Skalar**: Ini adalah tipe primitif seperti int, string, dll. Mereka biasanya ditugaskan ke bidang. Menggunakan `authorName` bidang sebagai contoh, dapat diberikan `String` skalar untuk menyimpan nama seperti “John Smith”. Skalar dapat berupa tipe input dan output.
+ **Input**: Input memungkinkan Anda untuk melewati sekelompok bidang sebagai argumen. Mereka terstruktur sangat mirip dengan objek, tetapi mereka dapat diteruskan sebagai argumen ke objek khusus. Input memungkinkan Anda untuk menentukan skalar, enum, dan input lain dalam cakupannya. Input hanya bisa berupa tipe input.
+ **Objek khusus**: Objek khusus melakukan operasi yang mengubah keadaan dan melakukan sebagian besar pengangkatan berat layanan. Ada tiga jenis objek khusus: kueri, mutasi, dan langganan. Kueri biasanya mengambil data; mutasi memanipulasi data; langganan membuka dan memelihara koneksi dua arah antara klien dan server untuk komunikasi konstan. Objek khusus bukanlah input atau output mengingat fungsinya.
+ **Enum**: Enum adalah daftar nilai hukum yang telah ditentukan sebelumnya. Jika Anda memanggil enum, nilainya hanya bisa menjadi apa yang didefinisikan dalam cakupannya. Misalnya, jika Anda memiliki enum yang disebut `trafficLights` menggambarkan daftar sinyal lalu lintas, itu bisa memiliki nilai seperti `redLight` dan `greenLight` tetapi tidak. `purpleLight` Lampu lalu lintas nyata hanya akan memiliki begitu banyak sinyal, sehingga Anda dapat menggunakan enum untuk mendefinisikannya dan memaksanya menjadi satu-satunya nilai hukum saat mereferensikan`trafficLight`. Enum dapat berupa tipe input dan output.
+ **Serikat/Antarmuka**: Serikat memungkinkan Anda mengembalikan satu atau lebih hal dalam permintaan tergantung pada data yang diminta oleh klien. Misalnya, jika Anda memiliki `Book` tipe dengan `title` bidang dan `Author` tipe dengan `name` bidang, Anda dapat membuat gabungan antara kedua jenis. *Jika klien Anda ingin menanyakan database untuk frasa “Julius Caesar”, serikat pekerja dapat mengembalikan *Julius Caesar* (drama oleh William Shakespeare) dari `Book` `title` dan *Julius Caesar* (penulis Commentarii de Bello Gallico) dari.* `Author` `name` Serikat pekerja hanya bisa menjadi tipe keluaran.

  Antarmuka adalah kumpulan bidang yang harus diimplementasikan objek. Ini sedikit mirip dengan antarmuka dalam bahasa pemrograman seperti Java di mana Anda harus mengimplementasikan bidang yang ditentukan dalam antarmuka. Misalnya, katakanlah Anda membuat antarmuka yang disebut `Book` yang berisi `title` bidang. Katakanlah Anda kemudian membuat tipe yang disebut `Novel` yang diimplementasikan`Book`. Anda `Novel` harus memasukkan `title` bidang. Namun, Anda juga `Novel` bisa menyertakan bidang lain yang tidak ada di antarmuka seperti `pageCount` atau`ISBN`. Antarmuka hanya dapat berupa tipe output.

Bagian berikut akan menjelaskan bagaimana setiap jenis bekerja di GraphQL.

## Objek
<a name="object-components"></a>

Objek GraphQL adalah tipe utama yang akan Anda lihat dalam kode produksi. Dalam GraphQL, Anda dapat menganggap objek sebagai pengelompokan bidang yang berbeda (mirip dengan variabel dalam bahasa lain), dengan setiap bidang ditentukan oleh tipe (biasanya skalar atau objek lain) yang dapat menyimpan nilai. Objek mewakili unit data yang dapat retrieved/manipulated berasal dari implementasi layanan Anda.

Jenis objek dideklarasikan menggunakan `Type` kata kunci. Mari kita memodifikasi contoh skema kita sedikit:

```
type Person {
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}
```

Jenis objek di sini adalah `Person` dan`Occupation`. Setiap objek memiliki bidangnya sendiri dengan tipenya sendiri. Salah satu fitur GraphQL adalah kemampuan untuk mengatur bidang ke jenis lain. Anda dapat melihat `occupation` bidang `Person` berisi jenis `Occupation` objek. Kita dapat membuat asosiasi ini karena GraphQL hanya mendeskripsikan data dan bukan implementasi layanan.

## Skalar
<a name="scalar-components"></a>

Skalar pada dasarnya adalah tipe primitif yang menyimpan nilai. Dalam AWS AppSync, ada dua jenis skalar: skalar GraphQL default dan skalar. AWS AppSync Skalar biasanya digunakan untuk menyimpan nilai bidang dalam tipe objek. Jenis GraphQL default `Int` meliputi`Float`,,,`String`, `Boolean` dan. `ID` Mari kita gunakan contoh sebelumnya lagi:

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}
```

Memilih `title` bidang `name` dan, keduanya memegang `String` skalar. `Name`dapat mengembalikan nilai string seperti "`John Smith`" dan judulnya dapat mengembalikan sesuatu seperti "`firefighter`”. Beberapa implementasi GraphQL juga mendukung skalar kustom menggunakan `Scalar` kata kunci dan menerapkan perilaku tipe. Namun, AWS AppSync saat ini **tidak mendukung** skalar khusus. Untuk daftar skalar, lihat [Jenis skalar](https://docs.aws.amazon.com//appsync/latest/devguide/scalars.html) di. AWS AppSync

## Masukan
<a name="input-components"></a>

Karena konsep tipe input dan output, ada batasan tertentu saat meneruskan argumen. Jenis yang biasanya perlu diteruskan, terutama objek, dibatasi. Anda dapat menggunakan tipe input untuk melewati aturan ini. Input adalah jenis yang berisi skalar, enum, dan jenis input lainnya.

Input didefinisikan menggunakan `input` kata kunci:

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

Seperti yang Anda lihat, kita dapat memiliki input terpisah yang meniru tipe aslinya. Masukan ini akan sering digunakan dalam operasi lapangan Anda seperti ini:

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

Perhatikan bagaimana kita masih meneruskan `occupationInput` di tempat `Occupation` untuk membuat`Person`. 

Ini hanyalah satu skenario untuk input. Mereka tidak perlu menyalin objek 1:1, dan dalam kode produksi, kemungkinan besar Anda tidak akan menggunakannya seperti ini. Ini adalah praktik yang baik untuk memanfaatkan skema GraphQL dengan mendefinisikan hanya apa yang perlu Anda masukan sebagai argumen.

Juga, input yang sama dapat digunakan dalam beberapa operasi, tetapi kami tidak menyarankan melakukan ini. Setiap operasi idealnya harus berisi salinan input uniknya sendiri jika persyaratan skema berubah.

## Benda khusus
<a name="special-object-components"></a>

GraphQL menyimpan beberapa kata kunci untuk objek khusus yang menentukan beberapa logika bisnis untuk bagaimana skema Anda akan data. retrieve/manipulate Paling-paling, bisa ada salah satu dari masing-masing kata kunci ini dalam skema. Mereka bertindak sebagai titik masuk untuk semua data yang diminta yang dijalankan klien Anda terhadap layanan GraphQL Anda. 

Objek khusus juga didefinisikan menggunakan `type` kata kunci. Meskipun mereka digunakan secara berbeda dari tipe objek biasa, implementasinya sangat mirip.

------
#### [ Queries ]

Kueri sangat mirip dengan `GET` operasi karena mereka melakukan pengambilan hanya-baca untuk mendapatkan data dari sumber Anda. Dalam GraphQL, `Query` mendefinisikan semua titik masuk untuk klien yang membuat permintaan terhadap server Anda. Akan selalu ada `Query` dalam implementasi GraphQL Anda.

Berikut adalah jenis objek `Query` dan modifikasi yang kami gunakan dalam contoh skema kami sebelumnya:

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
type Query {                                   
  people: [Person]
}
```

Kami `Query` berisi bidang `people` yang disebut yang mengembalikan daftar `Person` contoh dari sumber data. Katakanlah kita perlu mengubah perilaku aplikasi kita, dan sekarang kita perlu mengembalikan daftar hanya `Occupation` instance untuk beberapa tujuan terpisah. Kami cukup menambahkannya ke kueri:

```
type Query {                                   
  people: [Person]
  occupations: [Occupation]
}
```

Di GraphQL, kami dapat memperlakukan kueri kami sebagai sumber permintaan tunggal. Seperti yang Anda lihat, ini berpotensi jauh lebih sederhana daripada RESTful implementasi yang mungkin menggunakan titik akhir yang berbeda untuk mencapai hal yang sama (`.../api/1/people`dan`.../api/1/occupations`).

Dengan asumsi kita memiliki implementasi resolver untuk query ini, kita sekarang dapat melakukan query yang sebenarnya. Sementara `Query` jenisnya ada, kita harus secara eksplisit memanggilnya agar dapat dijalankan dalam kode aplikasi. Ini dapat dilakukan dengan menggunakan `query` kata kunci:

```
query getItems {
   people {
      name
   }
   occupations {
      title
   }
}
```

Seperti yang Anda lihat, kueri ini dipanggil `getItems` dan dikembalikan `people` (daftar `Person` objek) dan `occupations` (daftar `Occupation` objek). Di`people`, kami hanya mengembalikan `name` bidang masing-masing`Person`, sementara kami mengembalikan `title` bidang masing-masing`Occupation`. Responsnya mungkin terlihat seperti ini:

```
{
  "data": {
    "people": [
      {
        "name": "John Smith"
      },
      {
        "name": "Andrew Miller"
      },
      .
      .
      .
    ],
    "occupations": [
      {
        "title": "Firefighter"
      },
      {
        "title": "Bookkeeper"
      },
      .
      .
      .
    ]
  }
}
```

Contoh respon menunjukkan bagaimana data mengikuti bentuk query. Setiap entri yang diambil tercantum dalam lingkup bidang. `people`dan mengembalikan `occupations` hal-hal sebagai daftar terpisah. Meskipun berguna, mungkin lebih mudah untuk memodifikasi kueri untuk mengembalikan daftar nama dan pekerjaan orang:

```
query getItems {
   people {
      name   
      occupation {
        title
      }
}
```

Ini adalah modifikasi hukum karena `Person` tipe kami berisi `occupation` bidang tipe`Occupation`. Ketika terdaftar dalam lingkup`people`, kami mengembalikan masing-masing `Person` `name` bersama dengan yang terkait dengannya `Occupation``title`. Responsnya mungkin terlihat seperti ini:

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",
        "occupation": {
          "title": "Firefighter"
        }
      },
      {
        "name": "Andrew Miller",
        "occupation": {
          "title": "Bookkeeper"
        }
      },
      .
      .
      .
    ]
  }
}
```

------
#### [ Mutations ]

Mutasi mirip dengan operasi yang mengubah keadaan seperti atau. `PUT` `POST` Mereka melakukan operasi tulis untuk memodifikasi data di sumber, lalu mengambil responsnya. Mereka menentukan titik masuk Anda untuk permintaan modifikasi data. Tidak seperti kueri, mutasi mungkin atau mungkin tidak termasuk dalam skema tergantung pada kebutuhan proyek. Berikut mutasi dari contoh skema:

```
type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
```

`addPerson`Bidang mewakili satu titik masuk yang menambahkan a `Person` ke sumber data. `addPerson`adalah nama bidang;`id`,`name`, dan `age` merupakan parameter; dan `Person` merupakan tipe pengembalian. Melihat kembali `Person` jenisnya:

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
```

Kami menambahkan `occupation` bidang. Namun, kami tidak dapat mengatur bidang ini secara `Occupation` langsung karena objek tidak dapat diteruskan sebagai argumen; mereka benar-benar tipe keluaran. Sebagai gantinya, kita harus meneruskan input dengan bidang yang sama sebagai argumen:

```
input occupationInput {
  title: String
}
```

 Kami juga dapat dengan mudah memperbarui kami `addPerson` untuk memasukkan ini sebagai parameter saat membuat `Person` instance baru:

```
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
```

Berikut skema yang diperbarui:

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

Perhatikan bahwa `occupation` akan lulus di `title` bidang dari `occupationInput` untuk menyelesaikan pembuatan `Person` bukan `Occupation` objek asli. Dengan asumsi kita memiliki implementasi resolver untuk`addPerson`, kita sekarang dapat melakukan mutasi yang sebenarnya. Sementara `Mutation` jenisnya ada, kita harus secara eksplisit memanggilnya agar dapat dijalankan dalam kode aplikasi. Ini dapat dilakukan dengan menggunakan `mutation` kata kunci:

```
mutation createPerson {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput) {
    name
    age
    occupation {
      title
    }
  }
}
```

Mutasi ini disebut`createPerson`, dan `addPerson` merupakan operasi. Untuk membuat yang baru`Person`, kita bisa memasukkan argumen untuk`id`,`name`,`age`, dan`occupation`. Dalam lingkup`addPerson`, kita juga dapat melihat bidang lain seperti`name`,`age`, dll. Ini adalah tanggapan Anda; ini adalah bidang yang akan dikembalikan setelah `addPerson` operasi selesai. Inilah bagian terakhir dari contoh:

```
mutation createPerson {
  addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner") {
    id
    name
    age
    occupation {
      title
    }
  }
}
```

Menggunakan mutasi ini, hasilnya mungkin terlihat seperti ini:

```
{
  "data": {
    "addPerson": {
      "id": "1",
      "name": "Steve Powers",
      "age": "50",
      "occupation": {
        "title": "Miner"
      }
    }
  }
}
```

Seperti yang Anda lihat, respons mengembalikan nilai yang kami minta dalam format yang sama yang ditentukan dalam mutasi kami. Merupakan praktik yang baik untuk mengembalikan semua nilai yang telah dimodifikasi untuk mengurangi kebingungan dan kebutuhan akan lebih banyak kueri di masa mendatang. Mutasi memungkinkan Anda untuk memasukkan beberapa operasi dalam cakupannya. Mereka akan dijalankan secara berurutan dalam urutan yang tercantum dalam mutasi. Misalnya, jika kita membuat operasi lain `addOccupation` yang disebut yang menambahkan judul pekerjaan ke sumber data, kita dapat memanggil ini dalam mutasi setelahnya`addPerson`. `addPerson`akan ditangani terlebih dahulu diikuti oleh`addOccupation`.

------
#### [ Subscriptions ]

Langganan digunakan [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)untuk membuka koneksi dua arah yang langgeng antara server dan kliennya. Biasanya, klien akan berlangganan, atau mendengarkan, ke server. Setiap kali server membuat perubahan sisi server atau melakukan acara, klien berlangganan akan menerima pembaruan. Jenis protokol ini berguna ketika beberapa klien berlangganan dan perlu diberitahu tentang perubahan yang terjadi di server atau klien lain. Misalnya, langganan dapat digunakan untuk memperbarui umpan media sosial. Mungkin ada dua pengguna, Pengguna A dan Pengguna B, yang keduanya berlangganan pembaruan notifikasi otomatis setiap kali mereka menerima pesan langsung. Pengguna A pada Klien A dapat mengirim pesan langsung ke Pengguna B pada Klien B. Klien Pengguna A akan mengirim pesan langsung, yang akan diproses oleh server. Server kemudian akan mengirim pesan langsung ke akun Pengguna B saat mengirim pemberitahuan otomatis ke Klien B.

Berikut adalah contoh `Subscription` yang bisa kita tambahkan ke contoh skema:

```
type Subscription {                                   
  personAdded: Person
}
```

`personAdded`Bidang akan mengirim pesan ke klien berlangganan setiap kali baru `Person` ditambahkan ke sumber data. Dengan asumsi kami memiliki implementasi resolver untuk`personAdded`, kami sekarang dapat menggunakan langganan. Sementara `Subscription` jenisnya ada, kita harus secara eksplisit memanggilnya agar dapat dijalankan dalam kode aplikasi. Ini dapat dilakukan dengan menggunakan `subscription` kata kunci:

```
subscription personAddedOperation {
  personAdded {
    id
    name
  }
}
```

Langganan disebut`personAddedOperation`, dan operasinya`personAdded`. `personAdded`akan mengembalikan `id` dan `name` bidang `Person` instance baru. Melihat contoh mutasi, kami menambahkan `Person` menggunakan operasi ini:

```
addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner")
```

Jika klien kami berlangganan pembaruan yang baru ditambahkan`Person`, mereka mungkin melihat ini setelah `addPerson` dijalankan:

```
{
  "data": {
    "personAdded": {
      "id": "1",
      "name": "Steve Powers"
    }
  }
}
```

Di bawah ini adalah ringkasan dari apa yang ditawarkan langganan:

Langganan adalah saluran dua arah yang memungkinkan klien dan server menerima pembaruan yang cepat, tetapi stabil. Mereka biasanya menggunakan WebSocket protokol, yang menciptakan koneksi standar dan aman.

Langganan gesit karena mengurangi overhead pengaturan koneksi. Setelah berlangganan, klien dapat terus menjalankan langganan itu untuk jangka waktu yang lama. Mereka umumnya menggunakan sumber daya komputasi secara efisien dengan memungkinkan pengembang untuk menyesuaikan masa pakai langganan dan untuk mengkonfigurasi informasi apa yang akan diminta.

Secara umum, langganan memungkinkan klien untuk membuat beberapa langganan sekaligus. Sehubungan dengan itu AWS AppSync, langganan hanya digunakan untuk menerima pembaruan waktu nyata dari layanan. AWS AppSync Mereka tidak dapat digunakan untuk melakukan kueri atau mutasi.

Alternatif utama untuk langganan adalah polling, yang mengirimkan kueri pada interval yang ditetapkan untuk meminta data. Proses ini biasanya kurang efisien daripada langganan dan menempatkan banyak tekanan pada klien dan backend.

------

Satu hal yang tidak disebutkan dalam contoh skema kami adalah fakta bahwa tipe objek khusus Anda juga harus didefinisikan dalam `schema` root. Jadi saat Anda mengekspor skema AWS AppSync, mungkin terlihat seperti ini:

------
#### [ schema.graphql ]

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

.
.
.

type Query {                                   
  # code goes here
}
type Mutation {                                   
  # code goes here
}
type Subscription {                                   
  # code goes here
}
```

------

## Pencacahan
<a name="enum-components"></a>

Enumerasi, atau enum, adalah skalar khusus yang membatasi argumen hukum yang mungkin dimiliki tipe atau bidang. Ini berarti bahwa setiap kali enum didefinisikan dalam skema, jenis atau bidang terkait akan terbatas pada nilai dalam enum. Enum diserialkan sebagai skalar string. Perhatikan bahwa bahasa pemrograman yang berbeda dapat menangani enum GraphQL secara berbeda. Misalnya, tidak JavaScript memiliki dukungan enum asli, sehingga nilai enum dapat dipetakan ke nilai int sebagai gantinya.

Enum didefinisikan menggunakan `enum` kata kunci. Inilah contohnya:

```
enum trafficSignals {
  solidRed
  solidYellow
  solidGreen
  greenArrowLeft
  ...
}
```

Saat memanggil `trafficLights` enum, argumen hanya bisa`solidRed`,, `solidYellow``solidGreen`, dll. Adalah umum untuk menggunakan enum untuk menggambarkan hal-hal yang memiliki jumlah pilihan yang berbeda tetapi terbatas.

## Serikat Serikat/Antarmuka
<a name="union-interface-components"></a>

Lihat [Antarmuka dan serikat pekerja di GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html).

# Bidang GraphQL
<a name="graphql-fields"></a>

Bidang ada dalam lingkup tipe dan menyimpan nilai yang diminta dari layanan GraphQL. Ini sangat mirip dengan variabel dalam bahasa pemrograman lain. Misalnya, berikut adalah tipe `Person` objek:

```
type Person {                                  
   name: String                                  
   age: Int
}
```

Bidang dalam hal ini adalah `name` `age` dan dan memegang `Int` nilai `String` dan, masing-masing. Bidang objek seperti yang ditunjukkan di atas dapat digunakan sebagai input di bidang (operasi) kueri dan mutasi Anda. Misalnya, lihat `Query` di bawah ini:

```
type Query {                                   
  people: [Person]
}
```

`people`Bidang meminta semua contoh `Person` dari sumber data. Ketika Anda menambahkan atau mengambil `Person` di server GraphQL Anda, Anda dapat mengharapkan data mengikuti format tipe dan bidang Anda, yaitu, struktur data Anda dalam skema menentukan bagaimana itu akan disusun dalam respons Anda:

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",
        "age": "50"
      },
      {
        "name": "Andrew Miller",
        "age": "60"
      },
      .
      .
      .
    ]
  }
}
```

Bidang memainkan peran penting dalam penataan data. Ada beberapa properti tambahan yang dijelaskan di bawah ini yang dapat diterapkan ke bidang untuk penyesuaian lebih lanjut.

## Daftar
<a name="list-components"></a>

Daftar mengembalikan semua item dari jenis tertentu. Daftar dapat ditambahkan ke jenis bidang menggunakan tanda kurung`[]`: 

```
type Person { 
  name: String
  age: Int
}
type Query {                                   
  people: [Person]
}
```

Dalam`Query`, tanda kurung di sekitarnya `Person` menunjukkan bahwa Anda ingin mengembalikan semua contoh dari `Person` dari sumber data sebagai array. Sebagai tanggapan, `age` nilai `name` dan masing-masing `Person` akan dikembalikan sebagai daftar tunggal yang dibatasi:

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",         # Data of Person 1
        "age": "50"
      },
      {
        "name": "Andrew Miller",      # Data of Person 2
        "age": "60"
      },
      .                               # Data of Person N
      .
      .
    ]
  }
}
```

Anda tidak terbatas pada jenis objek khusus. Anda juga dapat menggunakan daftar di bidang jenis objek biasa.

## Non-nol
<a name="non-null-components"></a>

Non-null menunjukkan bidang yang tidak bisa null dalam respons. Anda dapat mengatur bidang ke non-null dengan menggunakan simbol: `!`

```
type Person { 
  name: String!
  age: Int
}
type Query {                                   
  people: [Person]
}
```

`name`Bidang tidak bisa secara eksplisit nol. Jika Anda menanyakan sumber data dan memberikan input nol untuk bidang ini, kesalahan akan muncul.

Anda dapat menggabungkan daftar dan non-null. Bandingkan pertanyaan ini:

```
type Query {                                   
  people: [Person!]      # Use case 1
}

.
.
.

type Query {                                   
  people: [Person]!      # Use case 2
}

.
.
.

type Query {                                   
  people: [Person!]!     # Use case 3
}
```

Dalam kasus penggunaan 1, daftar tidak dapat berisi item nol. Dalam kasus penggunaan 2, daftar itu sendiri tidak dapat diatur ke null. Dalam kasus penggunaan 3, daftar dan item-itemnya tidak bisa null. Namun, bagaimanapun, Anda masih dapat mengembalikan daftar kosong.

Seperti yang Anda lihat, ada banyak komponen bergerak di GraphQL. Pada bagian ini, kami menunjukkan struktur skema sederhana dan berbagai jenis dan bidang yang didukung skema. Di bagian berikut, Anda akan menemukan komponen lain dari GraphQL API dan bagaimana mereka bekerja dengan skema.