Firebase SQL Connect memungkinkan Anda membuat konektor untuk instance PostgreSQL yang dikelola dengan Google Cloud SQL. Konektor ini adalah kombinasi kueri dan mutasi untuk menggunakan data dari skema Anda.
Panduan Memulai memperkenalkan skema aplikasi ulasan film untuk PostgreSQL.
Panduan tersebut juga memperkenalkan operasi administratif yang dapat di-deploy dan ad hoc, termasuk mutasi.
- Mutasi yang dapat di-deploy adalah mutasi yang Anda terapkan untuk dipanggil dari aplikasi klien di konektor, dengan endpoint API yang Anda tentukan. SQL Connect mengintegrasikan autentikasi dan otorisasi ke dalam mutasi ini, dan menghasilkan SDK klien berdasarkan API Anda.
- Mutasi administratif ad hoc dijalankan dari lingkungan yang memiliki hak istimewa untuk mengisi dan mengelola tabel. Anda dapat membuat dan menjalankannya di Firebase konsol, dari lingkungan yang memiliki hak istimewa menggunakan Firebase Admin SDK, dan di lingkungan pengembangan lokal menggunakan ekstensi SQL Connect VS Code.
Panduan ini membahas lebih mendalam tentang mutasi yang dapat di-deploy.
Fitur mutasi SQL Connect
SQL Connect memungkinkan Anda melakukan mutasi dasar dengan semua cara yang Anda harapkan mengingat database PostgreSQL:
- Melakukan operasi CRUD
- Mengelola operasi multi-langkah dengan transaksi
Namun, dengan ekstensi SQL Connect ke GraphQL, Anda dapat menerapkan mutasi lanjutan untuk aplikasi yang lebih cepat dan lebih efisien:
- Menggunakan skalar kunci yang ditampilkan oleh banyak operasi untuk menyederhanakan operasi berulang pada data
- Menggunakan nilai server untuk mengisi data dengan operasi yang disediakan oleh server
- Melakukan kueri selama operasi mutasi multi-langkah untuk mencari data, sehingga menghemat baris kode dan perjalanan pulang pergi ke server.
Menggunakan kolom yang dihasilkan untuk menerapkan mutasi
Operasi SQL Connect akan memperluas kumpulan kolom yang otomatis dihasilkan oleh SQL Connect berdasarkan jenis dan hubungan jenis dalam skema Anda. Kolom ini dihasilkan oleh alat lokal setiap kali Anda mengedit skema.
Anda dapat menggunakan kolom yang dihasilkan untuk menerapkan mutasi, mulai dari membuat, memperbarui, dan menghapus data individual dalam satu tabel, hingga pembaruan multi-tabel yang lebih kompleks.Asumsikan skema Anda berisi jenis Movie dan jenis Actor terkait.
SQL Connect menghasilkan kolom movie_insert,
movie_update, movie_delete, dan lainnya.
Mutasi dengan
movie_insert kolom
|
Kolom |
Gunakan kolom ini untuk membuat satu film. mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) { movie_insert(data: { title: $title releaseYear: $releaseYear genre: $genre rating: $rating }) } |
Mutasi dengan
movie_update kolom
|
Kolom |
Gunakan kolom ini untuk memperbarui satu film berdasarkan kuncinya. mutation UpdateMovie($myKey: Movie_Key!, $genre: String, $rating: Int, $description: String) { movie_update(key: $myKey, data: { genre: $genre rating: $rating description: $description }) } |
Mutasi dengan
movie_delete kolom
|
Kolom |
Gunakan kolom ini untuk menghapus satu film berdasarkan kuncinya. mutation DeleteMovie($myKey: Movie_Key!) { movie_delete(key: $myKey) { key } } |
Elemen penting mutasi
SQL Connect mutasi adalah mutasi GraphQL dengan SQL Connect ekstensi. Sama seperti mutasi GraphQL biasa, Anda dapat menentukan nama operasi dan daftar variabel GraphQL.
SQL Connect memperluas kueri GraphQL dengan perintah yang disesuaikan seperti
@auth dan @transaction.
Jadi, mutasi berikut memiliki:
- Definisi jenis
mutation - Nama operasi (mutasi)
SignUp - Satu argumen operasi variabel
$username - Satu perintah,
@auth - Satu kolom
user_insert.
mutation SignUp($username: String!) @auth(level: USER) {
user_insert(data: {
id_expr: "auth.uid"
username: $username
})
}
Setiap argumen mutasi memerlukan deklarasi jenis, bawaan seperti String, atau jenis yang ditentukan skema kustom seperti Movie.
Menulis mutasi dasar
Anda dapat mulai menulis mutasi untuk membuat, memperbarui, dan menghapus data individual dari database.
Buat
Mari lakukan pembuatan dasar.
# Create a movie based on user input
mutation CreateMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
movie_insert(data: {
title: $title
releaseYear: $releaseYear
genre: $genre
rating: $rating
})
}
# Create a movie with default values
mutation CreateMovie2 {
movie_insert(data: {
title: "Sherlock Holmes"
releaseYear: 2009
genre: "Mystery"
rating: 5
})
}
Atau upsert.
# Movie upsert using combination of variables and literals
mutation UpsertMovie($title: String!) {
movie_upsert(data: {
title: $title
releaseYear: 2009
genre: "Mystery"
rating: 5
genre: "Mystery/Thriller"
})
}
Lakukan pembaruan
Berikut adalah pembaruan. Produser dan sutradara tentu berharap rating rata-rata tersebut sedang tren.
Kolom movie_update berisi argumen id yang diharapkan untuk mengidentifikasi data dan kolom data yang dapat Anda gunakan untuk menetapkan nilai dalam pembaruan ini.
mutation UpdateMovie(
$id: UUID!,
$genre: String!,
$rating: Int!,
$description: String!
) {
movie_update(id: $id,
data: {
genre: $genre
rating: $rating
description: $description
})
}
Untuk melakukan beberapa pembaruan, gunakan kolom movie_updateMany.
# Multiple updates (increase all ratings of a genre)
mutation IncreaseRatingForGenre($genre: String!, $rating: Int!) {
movie_updateMany(
where: { genre: { eq: $genre } },
data:
{
rating: $rating
})
}
Menggunakan operasi penambahan, pengurangan, penambahan, dan penambahan dengan _update
Saat berada dalam mutasi _update dan _updateMany, Anda dapat menetapkan nilai secara eksplisit di
data:, tetapi sering kali lebih masuk akal untuk menerapkan operator seperti penambahan untuk memperbarui
nilai.
Untuk mengubah contoh pembaruan sebelumnya, asumsikan Anda ingin menambahkan rating film tertentu. Anda dapat menggunakan sintaksis rating_update dengan operator inc.
mutation UpdateMovie(
$id: UUID!,
$ratingIncrement: Int!
) {
movie_update(id: $id, data: {
rating_update: {
inc: $ratingIncrement
}
})
}
SQL Connect mendukung operator berikut untuk pembaruan kolom:
incuntuk menambahkan jenis dataInt,Int64,Float,Date, danTimestampdecuntuk mengurangi jenis dataInt,Int64,Float,Date, danTimestamp
Untuk daftar, Anda juga dapat memperbarui dengan nilai individual atau daftar nilai menggunakan:
adduntuk menambahkan item jika belum ada ke jenis daftar, kecuali daftar Vektorremoveuntuk menghapus semua item, jika ada, dari jenis daftar, kecuali daftar Vektorappenduntuk menambahkan item ke jenis daftar, kecuali daftar Vektorprependuntuk menambahkan item ke jenis daftar, kecuali daftar Vektor
Lakukan penghapusan
Tentu saja Anda dapat menghapus data film. Pelestari film tentu ingin film fisik dipertahankan selama mungkin.
# Delete by key
mutation DeleteMovie($id: UUID!) {
movie_delete(id: $id)
}
Di sini Anda dapat menggunakan _deleteMany.
# Multiple deletes
mutation DeleteUnpopularMovies($minRating: Int!) {
movie_deleteMany(where: { rating: { le: $minRating } })
}
Menulis mutasi pada relasi
Amati cara menggunakan mutasi _upsert implisit pada relasi.
# Create or update a one to one relation
mutation MovieMetadataUpsert($movieId: UUID!, $director: String!) {
movieMetadata_upsert(
data: { movie: { id: $movieId }, director: $director }
)
}
Mendesain skema untuk mutasi yang efisien
SQL Connect menyediakan dua fitur penting yang memungkinkan Anda menulis mutasi yang lebih efisien dan menghemat operasi pulang pergi.
Skalar kunci adalah ID objek ringkas yang SQL Connect otomatis dirakit dari kolom kunci dalam skema Anda. Skalar kunci adalah tentang efisiensi, yang memungkinkan Anda menemukan informasi tentang identitas dan struktur data dalam satu panggilan. Skalar kunci sangat berguna saat Anda ingin melakukan tindakan berurutan pada data baru dan memerlukan ID unik untuk diteruskan ke operasi mendatang, dan juga saat Anda ingin mengakses kunci relasional untuk melakukan operasi tambahan yang lebih kompleks.
Dengan menggunakan nilai server, Anda dapat secara efektif mengizinkan server mengisi
kolom dalam tabel secara dinamis menggunakan nilai yang disimpan atau mudah dihitung sesuai dengan
ekspresi CEL sisi server tertentu dalam argumen expr. Misalnya, Anda
dapat menentukan kolom dengan stempel waktu yang diterapkan saat kolom diakses menggunakan
waktu yang disimpan dalam permintaan operasi, updatedAt: Timestamp!
@default(expr: "request.time").
Menulis mutasi lanjutan: mengizinkan SQL Connect menyediakan nilai menggunakan field_expr sintaksis
Seperti yang dibahas dalam skalar kunci dan nilai server,
Anda dapat mendesain skema sehingga server mengisi nilai untuk kolom umum
seperti ids dan tanggal sebagai respons terhadap permintaan klien.
Selain itu, Anda dapat menggunakan data, seperti ID pengguna, yang dikirim dalam
SQL Connect request objek dari aplikasi klien.
Saat menerapkan mutasi, gunakan sintaksis field_expr untuk memicu pembaruan yang dihasilkan server atau mengakses data dari permintaan. Misalnya, untuk meneruskan
otorisasi uid yang disimpan dalam permintaan ke operasi _upsert, teruskan
"auth.uid" di kolom userId_expr.
# Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}
# Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
Atau, dalam aplikasi daftar tugas yang sudah dikenal, saat membuat daftar tugas baru, Anda dapat meneruskan id_expr untuk menginstruksikan server agar otomatis membuat UUID untuk daftar tersebut.
mutation CreateTodoListWithFirstItem(
$listName: String!
) @transaction {
# Step 1
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
}
Untuk mengetahui informasi selengkapnya, lihat skalar _Expr dalam
referensi skalar.
Menulis mutasi lanjutan: operasi multi-langkah
Ada banyak situasi ketika Anda mungkin ingin menyertakan beberapa kolom tulis (seperti penyisipan) dalam satu mutasi. Anda mungkin juga ingin membaca database selama eksekusi mutasi untuk mencari dan memverifikasi data yang ada sebelum melakukan, misalnya, penyisipan atau pembaruan. Opsi ini menghemat operasi pulang pergi dan oleh karena itu, menghemat biaya.
SQL Connect memungkinkan Anda melakukan logika multi-langkah dalam mutasi dengan mendukung:
Beberapa kolom tulis
Beberapa kolom baca dalam mutasi Anda (menggunakan kata kunci kolom
query).Perintah
@transactiondirective, yang menyediakan dukungan transaksi yang sudah dikenal dari database relasional.Perintah
@checkdirective, yang memungkinkan Anda mengevaluasi konten baca menggunakan ekspresi CEL, dan berdasarkan hasil evaluasi tersebut:- Lanjutkan dengan pembuatan, pembaruan, dan penghapusan yang ditentukan oleh mutasi
- Lanjutkan untuk menampilkan hasil kolom kueri
- Gunakan pesan yang ditampilkan untuk melakukan logika yang sesuai dalam kode klien Anda
Perintah
@redact, yang memungkinkan Anda menghapus hasil kolom kueri dari hasil protokol kabel.Binding
responseCEL, yang menyimpan hasil kumulatif dari semua mutasi dan kueri yang dilakukan dalam operasi multi-langkah yang kompleks. Anda dapat mengakses bindingresponse:- Dalam perintah
@check, melalui argumenexpr: - Dengan nilai server, menggunakan sintaksis
field_expr
- Dalam perintah
Perintah @transaction
Dukungan untuk mutasi multi-langkah mencakup penanganan error menggunakan transaksi.
Perintah @transaction mewajibkan mutasi - dengan satu kolom tulis (misalnya, _insert atau _update) atau dengan beberapa kolom tulis - selalu berjalan dalam transaksi database.
Mutasi tanpa
@transactionmenjalankan setiap kolom root satu per satu secara berurutan. Operasi ini menampilkan error sebagai error kolom parsial, tetapi tidak menampilkan dampak dari eksekusi berikutnya.Mutasi dengan
@transactiondijamin akan berhasil sepenuhnya atau gagal sepenuhnya. Jika salah satu kolom dalam transaksi gagal, seluruh transaksi akan di-roll back.
Perintah @check dan @redact
Perintah @check memverifikasi bahwa kolom yang ditentukan ada dalam hasil kueri. Ekspresi Common Expression Language (CEL) digunakan untuk menguji nilai kolom. Perilaku default perintah ini adalah memeriksa dan menolak node yang nilainya adalah null atau [] (daftar kosong).
Perintah @redact menghapus sebagian respons dari klien. Kolom yang dihapus masih dievaluasi untuk efek samping (termasuk perubahan data dan @check) dan hasilnya masih tersedia untuk langkah-langkah berikutnya dalam ekspresi CEL.
Menggunakan @check, @check(message:), dan @redact
Penggunaan utama untuk @check dan @redact adalah mencari data terkait untuk memutuskan apakah operasi tertentu harus diotorisasi, menggunakan pencarian dalam logika tetapi menyembunyikannya dari klien. Kueri Anda dapat menampilkan pesan yang berguna untuk penanganan yang benar dalam kode klien.
query GetMovieEditors($movieId: UUID!) @auth(level: USER) {
moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
}
moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
user {
id
username
}
}
}
Untuk mempelajari lebih lanjut perintah @check dan @redact dalam pemeriksaan otorisasi,
lihat pembahasan pencarian data otorisasi.
Menggunakan @check untuk memvalidasi kunci
Beberapa kolom mutasi, seperti _update, mungkin tidak beroperasi jika data dengan kunci yang ditentukan tidak ada. Demikian pula, pencarian mungkin menampilkan null atau daftar kosong. Hal ini tidak dianggap sebagai error dan oleh karena itu tidak akan memicu rollback.
Untuk mencegah hasil ini, uji apakah kunci dapat ditemukan menggunakan perintah @check.
# Delete by key, error if not found
mutation MustDeleteMovie($id: UUID!) @transaction {
movie_delete(id: $id) @check(expr: "this != null", message: "Movie not found, therefore nothing is deleted")
}
Menggunakan binding response untuk menggabungkan mutasi multi-langkah
Pendekatan dasar untuk membuat data terkait, misalnya Movie baru dan
entri MovieMetadata terkait, adalah:
- Memanggil mutasi
_insertuntukMovie - Menyimpan kunci yang ditampilkan dari film yang dibuat
- Kemudian, memanggil mutasi
_insertkedua untuk membuat dataMovieMetadata.
Namun, dengan SQL Connect, Anda dapat menangani kasus umum ini dalam satu
operasi multi-langkah dengan mengakses hasil _insert pertama di
_insert kedua.
Membuat aplikasi ulasan film yang berhasil membutuhkan banyak pekerjaan. Mari lacak daftar tugas kita dengan contoh baru.
Menggunakan response untuk menetapkan kolom dengan nilai server
Dalam mutasi daftar tugas berikut:
- Binding
responsemewakili objek respons parsial sejauh ini, yang mencakup semua kolom mutasi tingkat atas sebelum kolom saat ini. - Hasil operasi
todoList_insertawal, yang menampilkanid(kunci), diakses nanti diresponse.todoList_insert.idsehingga kita dapat langsung menyisipkan item tugas baru.
mutation CreateTodoListWithFirstItem(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1:
todoList_insert(data: {
id_expr: "uuidV4()", # <-- auto-generated. Or a column-level @default on `type TodoList` will also work
name: $listName,
})
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
content: $itemContent,
})
}
Menggunakan response untuk memvalidasi kolom menggunakan @check
response juga tersedia di @check(expr: "..."), sehingga Anda dapat menggunakannya untuk
membuat logika sisi server yang lebih rumit. Jika digabungkan dengan langkah query { … } dalam mutasi, Anda dapat mencapai lebih banyak hal tanpa perjalanan pulang pergi klien-server tambahan.
Dalam contoh berikut, perhatikan: bahwa @check sudah memiliki akses ke response.query karena @check selalu berjalan setelah langkah yang dilampirkan.
mutation CreateTodoInNamedList(
$listName: String!,
$itemContent: String!
) @transaction {
# Sub-step 1: Look up List.id by its name
query
@check(expr: "response.query.todoLists.size() > 0", message: "No such TodoList with the name!")
@check(expr: "response.query.todoLists.size() < 2", message: "Ambiguous listName!") {
todoLists(where: { name: $listName }) {
id
}
}
# Sub-step 2:
todo_insert(data: {
listId_expr: "response.todoLists[0].id" # <-- Now we have the parent list ID to insert to
content: $itemContent,
})
}
Untuk mengetahui informasi selengkapnya tentang binding response, lihat
referensi CEL.
Memahami operasi yang terganggu dengan @transaction dan query @check
Mutasi multi-langkah dapat mengalami error:
- Operasi database mungkin gagal.
- Logika kueri
@checkdapat menghentikan operasi.
SQL Connect merekomendasikan agar Anda menggunakan perintah @transaction dengan
mutasi multi-langkah. Hal ini menghasilkan database dan hasil mutasi yang lebih konsisten dan lebih mudah ditangani dalam kode klien:
- Pada error pertama atau
@checkyang gagal, operasi akan dihentikan, sehingga tidak perlu mengelola eksekusi kolom berikutnya atau evaluasi CEL. - Rollback dilakukan sebagai respons terhadap error database atau logika
@check, sehingga menghasilkan status database yang konsisten. - Error rollback selalu ditampilkan ke kode klien.
Mungkin ada beberapa kasus penggunaan saat Anda memilih untuk tidak menggunakan @transaction: Anda dapat memilih konsistensi eventual jika, misalnya, Anda memerlukan throughput, skalabilitas, atau ketersediaan yang lebih tinggi. Namun, Anda perlu mengelola database dan kode klien untuk memungkinkan hasil:
- Jika satu kolom gagal karena operasi database, kolom berikutnya akan terus dieksekusi. Namun,
@checkyang gagal tetap menghentikan seluruh operasi. - Rollback tidak dilakukan, yang berarti status database campuran dengan beberapa pembaruan yang berhasil dan beberapa pembaruan yang gagal.
- Operasi Anda dengan
@checkdapat memberikan hasil yang lebih tidak konsisten jika logika@checkmenggunakan hasil pembacaan dan/atau penulisan pada langkah sebelumnya. - Hasil yang ditampilkan ke kode klien akan berisi campuran respons keberhasilan dan kegagalan yang lebih kompleks untuk ditangani.
Perintah untuk mutasi SQL Connect
Selain perintah yang Anda gunakan dalam menentukan jenis dan tabel,
SQL Connect menyediakan perintah @auth, @check, @redact dan
@transaction untuk meningkatkan perilaku operasi.
| Perintah | Berlaku untuk | Deskripsi |
|---|---|---|
@auth |
Kueri dan mutasi | Menentukan kebijakan otorisasi untuk kueri atau mutasi. Lihat panduan otorisasi dan pengesahan. |
@check |
Kolom query dalam operasi multi-langkah |
Memverifikasi bahwa kolom yang ditentukan ada dalam hasil kueri. Ekspresi Common Expression Language (CEL) digunakan untuk menguji nilai kolom. Lihat Operasi multi-langkah. |
@redact |
Kueri | Menghapus sebagian respons dari klien. Lihat Operasi multi-langkah. |
@transaction |
Mutasi | Mewajibkan mutasi untuk selalu berjalan dalam transaksi database. Lihat Operasi multi-langkah. |
Langkah berikutnya
Anda mungkin tertarik dengan:
- Membuat mutasi untuk aplikasi Anda menggunakan alat bantuan AI
- Mengotorisasi mutasi Anda sesuai panduan otorisasi
- Memanggil mutasi dari kode klien untuk web, iOS, Android dan Flutter.
- Melakukan operasi data massal dengan mutasi