Antarmuka dan serikat pekerja di GraphQL - AWS AppSync

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

Sistem tipe GraphQL mendukungAntarmuka. Antarmuka memperlihatkan sekumpulan bidang tertentu yang harus disertakan tipe untuk mengimplementasikan antarmuka.

Sistem tipe GraphQL juga mendukungSerikat pekerja. 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

Kita bisa mewakili sebuahEventantarmuka yang mewakili segala jenis aktivitas atau pengumpulan orang. Beberapa jenis acara yang mungkinConcert,Conference, danFestival. Semua jenis ini memiliki karakteristik umum, termasuk nama, tempat di mana acara berlangsung, dan tanggal mulai dan berakhir. Tipe-tipe ini juga memiliki perbedaan; aConferencemenawarkan daftar pembicara dan lokakarya, sementaraConcertmenampilkan band pertunjukan.

Dalam Schema Definition Language (SDL),Eventantarmuka didefinisikan sebagai berikut:

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

Dan masing-masing jenis mengimplementasikanEventantarmuka 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 kita tambahkanfindEventsByVenuebidang 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] }

ThefindEventsByVenuemengembalikan daftarEvent. Karena bidang antarmuka GraphQL umum untuk semua jenis implementasi, dimungkinkan untuk memilih bidang apa pun diEventantarmuka (id,name,startsAt,endsAt,venue, danminAgeRestriction). Selain itu, Anda dapat mengakses bidang pada jenis implementasi apa pun menggunakan GraphQLpecahan, 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

Seperti yang dinyatakan sebelumnya, serikat pekerja tidak mendefinisikan kumpulan bidang umum. Hasil pencarian mungkin mewakili berbagai jenis. MenggunakanEventskema, Anda dapat mendefinisikanSearchResultserikat 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 diSearchResultserikat pekerja, 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 diAWS AppSync

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 mungkinSearchResultserikat didefinisikan (yaitu,Conference,Festival,Concert, atauVenue).

Karena logika untuk mengidentifikasiFestivaldari aVenueatauConferencetergantung pada persyaratan aplikasi, mesin GraphQL harus diberi petunjuk untuk mengidentifikasi kemungkinan jenis kami dari hasil mentah.

denganAWS AppSync, petunjuk ini diwakili oleh bidang meta bernama__typename, yang nilainya sesuai dengan nama tipe objek yang diidentifikasi.__typenamediperlukan untuk tipe pengembalian yang merupakan antarmuka atau serikat pekerja.

Contoh resolusi tipe

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

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 keQuery.searchlapangan. DiResolversbagian, pilihLampirkan, buat yang baruSumber Datadari jenisTIDAK ADA, dan kemudian beri namaStubDataSource. 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 dariidbidang, logika resolusi tipe harus menguraiidbidang untuk mengekstrak nama tipe dan kemudian menambahkan__typenamebidang untuk setiap 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 berbeda yang memeriksa keberadaan bidang tertentu atau bahkan kombinasi bidang. Artinya, Anda bisa mendeteksi keberadaanperformersbidang untuk mengidentifikasiFestivalatau kombinasi darispeakersdanworkshopsbidang untuk mengidentifikasiConference. Pada akhirnya, terserah Anda untuk menentukan logika yang ingin Anda gunakan.