View a markdown version of this page

Jenis GraphQL - AWS AppSync GraphQL

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

Jenis GraphQL

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 menjadi input dan output. Input adalah tipe yang diizinkan untuk diteruskan sebagai argumen untuk tipe objek khusus (Query,Mutation, dll.), Sedangkan tipe output digunakan secara ketat untuk menyimpan dan mengembalikan data. Daftar jenis dan kategorisasinya tercantum di bawah ini:

  • Objek: Objek berisi bidang yang menggambarkan entitas. Misalnya, sebuah objek bisa berupa sesuatu seperti a book dengan bidang yang menggambarkan karakteristiknya sepertiauthorName,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 ditetapkan String skalar untuk menyimpan nama seperti “John Smith”. Scalar dapat berupa tipe input dan output.

  • In put: Input memungkinkan Anda untuk meneruskan 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 lainnya dalam ruang lingkupnya. Input hanya bisa berupa jenis input.

  • Objek khusus: Objek khusus melakukan operasi pengubah keadaan dan melakukan sebagian besar pengangkatan berat layanan. Ada tiga jenis objek khusus: query, mutasi, dan langganan. Kueri biasanya mengambil data; mutasi memanipulasi data; langganan membuka dan mempertahankan koneksi dua arah antara klien dan server untuk komunikasi konstan. Objek khusus bukan 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 tidakpurpleLight. 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.

  • Unions/interfaces: Serikat pekerja 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 penyatuan 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 Com mentarii de Bello Gallico) dari. Author name Serikat hanya bisa menjadi tipe output.

    Antarmuka adalah kumpulan bidang yang harus diterapkan 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 Book yang disebut yang berisi title bidang. Katakanlah Anda kemudian membuat tipe yang disebut Novel yang diimplementasikanBook. Anda Novel harus menyertakan title bidang. Namun, Anda juga Novel dapat menyertakan bidang lain yang tidak ada di antarmuka seperti pageCount atauISBN. Antarmuka hanya bisa berupa tipe output.

Bagian berikut akan menjelaskan bagaimana setiap jenis bekerja di GraphQL.

Objek

Objek GraphQL adalah tipe utama yang akan Anda lihat dalam kode produksi. Di 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 berasal retrieved/manipulated dari implementasi layanan Anda.

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

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

Jenis objek di sini adalah Person danOccupation. 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 di Person berisi tipe Occupation objek. Kita dapat membuat asosiasi ini karena GraphQL hanya menggambarkan data dan bukan implementasi layanan.

Skalar

Skalar pada dasarnya adalah tipe primitif yang memegang nilai. Di AWS AppSync, ada dua jenis skalar: skalar GraphQL default dan skalar. AWS AppSync Scalar biasanya digunakan untuk menyimpan nilai bidang dalam tipe objek. Jenis GraphQL default termasukInt,Float,, StringBoolean, danID. 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. Namedapat mengembalikan nilai string seperti "John Smith" dan judul dapat mengembalikan sesuatu seperti "firefighter”. Beberapa implementasi GraphQL juga mendukung skalar khusus menggunakan Scalar kata kunci dan mengimplementasikan perilaku tipe. Namun, AWS AppSync saat ini tidak mendukung sk alar khusus. Untuk daftar skalar, lihat Jenis skalar di. AWS AppSync

Masukan

Karena konsep tipe input dan output, ada batasan tertentu ketika meneruskan argumen. Jenis yang biasanya perlu diteruskan, terutama objek, dibatasi. Anda dapat menggunakan jenis 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. Input 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 occupationInput menggantikan Occupation untuk membuatPerson.

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 hanya mendefinisikan apa yang perlu Anda masukkan 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.

Objek khusus

GraphQL menyimpan beberapa kata kunci untuk objek khusus yang menentukan beberapa logika bisnis untuk bagaimana skema Anda akan retrieve/manipulate data. Paling-paling, mungkin ada 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 baca-saja untuk mendapatkan data dari sumber Anda. Di GraphQL, men Query definisikan 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 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 instance dari sumber data. Katakanlah kita perlu mengubah perilaku aplikasi kita, dan sekarang kita perlu mengembalikan daftar hanya Occupation contoh untuk beberapa tujuan terpisah. Kita cukup menambahkannya ke kueri:

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

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

Dengan asumsi kita memiliki implementasi resolver untuk kueri ini, kita sekarang dapat melakukan kueri yang sebenarnya. Sementara ti Query penya ada, kita harus secara eksplisit memanggilnya agar dapat berjalan 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 mengembalikan people (daftar Person objek) dan occupations (daftar Occupation objek). Dipeople, kami hanya mengembalikan name bidang masing-masingPerson, sementara kami mengembalikan title bidang masing-masingOccupation. Tanggapannya mungkin terlihat seperti ini:

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

Contoh respons menunjukkan bagaimana data mengikuti bentuk kueri. Setiap entri yang diambil terdaftar dalam lingkup bidang. peopledan occupations mengembalikan 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 tipeOccupation. Ketika terdaftar dalam lingkuppeople, kami mengembalikan masing-masing Person name bersama dengan yang terkait Occupationtitle. Tanggapannya mungkin terlihat seperti ini:

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

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

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

Bid addPerson ang mewakili satu titik masuk yang menambahkan Person a ke sumber data. addPersonadalah nama bidang;id,name, dan age merupakan parameter; dan Person merupakan tipe pengembalian. Melihat kembali jen Person isnya:

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

Kami menambahkan occupation bidang. Namun, kita 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 melewati title bidang dari occupationInput untuk menyelesaikan pembuatan al Person ih-alih Occupation objek asli. Dengan asumsi kita memiliki implementasi resolver untukaddPerson, kita sekarang dapat melakukan mutasi yang sebenarnya. Sementara ti Mutation penya ada, kita harus secara eksplisit memanggilnya agar dapat berjalan 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 disebutcreatePerson, dan addPerson merupakan operasi. Untuk membuat yang baruPerson, kita bisa memasukkan argumen untukid,name,age, danoccupation. Dalam lingkupaddPerson, kita juga dapat melihat bidang lain sepertiname,age, dll. Ini adalah tanggapan Anda; ini adalah bidang yang akan dikembalikan setelah addPerson operasi selesai. Berikut adalah 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. Ini adalah praktik yang baik untuk mengembalikan semua nilai yang dimodifikasi untuk mengurangi kebingungan dan kebutuhan akan lebih banyak kueri di masa mendatang. Mutasi memungkinkan Anda untuk memasukkan beberapa operasi dalam ruang lingkupnya. 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 setelahnyaaddPerson. addPersonakan ditangani terlebih dahulu diikuti olehaddOccupation.

Subscriptions

Langganan digunakan WebSockets 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 yang 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 pemberitahuan 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 sambil mengirim pemberitahuan otomatis ke Klien B.

Berikut adalah contoh Subscription yang dapat kita tambahkan ke contoh skema:

type Subscription { personAdded: Person }

Bid personAdded ang akan mengirim pesan ke klien berlangganan setiap kali yang baru Person ditambahkan ke sumber data. Dengan asumsi kita memiliki implementasi resolver untukpersonAdded, kita sekarang dapat menggunakan langganan. Sementara ti Subscription penya ada, kita harus secara eksplisit memanggilnya agar dapat berjalan dalam kode aplikasi. Ini dapat dilakukan dengan menggunakan subscription kata kunci:

subscription personAddedOperation { personAdded { id name } }

Langganan dipanggilpersonAddedOperation, dan operasinyapersonAdded. personAddedakan mengembalikan name bidang id dan 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 untuk yang baru ditambahkanPerson, mereka mungkin melihat ini setelah di addPerson jalankan:

{ "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. Dalam hal ini AWS AppSync, langganan hanya digunakan untuk menerima pembaruan real-time dari AWS AppSync layanan. Mereka tidak dapat digunakan untuk melakukan kueri atau mutasi.

Alternatif utama untuk langganan adalah polling, yang mengirimkan kueri pada interval yang ditentukan 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 ketika 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 }

Pencacatan

Enumerasi, atau enum, adalah skalar khusus yang membatasi argumen hukum yang mungkin dimiliki suatu jenis atau bidang. Ini berarti bahwa setiap kali enum didefinisikan dalam skema, jenis atau bidang yang terkait akan terbatas pada nilai-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 bisasolidRed, solidYellowsolidGreen, dll. Adalah umum untuk menggunakan enum untuk menggambarkan hal-hal yang memiliki jumlah pilihan yang berbeda tetapi terbatas.

Unions/Interfaces

Lihat Antar muka dan serikat pekerja di GraphQL.