Awalnya diposting di Tanpa Server pada 2 Juli 2019
Mengekspos database sederhana melalui GraphQL API membutuhkan banyak kode dan infrastruktur khusus:benar atau salah?
Bagi mereka yang menjawab "benar", kami di sini untuk menunjukkan kepada Anda bahwa membuat GraphQL API sebenarnya cukup mudah, dengan beberapa contoh konkret untuk mengilustrasikan mengapa dan bagaimana caranya.
(Jika Anda sudah tahu betapa mudahnya membangun GraphQL API dengan Tanpa Server, ada banyak hal untuk Anda juga di artikel ini.)
GraphQL adalah bahasa kueri untuk API web. Ada perbedaan utama antara REST API konvensional dan API berdasarkan GraphQL:dengan GraphQL, Anda dapat menggunakan satu permintaan untuk mengambil beberapa entitas sekaligus. Ini menghasilkan pemuatan halaman yang lebih cepat dan memungkinkan struktur yang lebih sederhana untuk aplikasi frontend Anda, menghasilkan pengalaman web yang lebih baik untuk semua orang. Jika Anda belum pernah menggunakan GraphQL sebelumnya, kami sarankan Anda melihat tutorial GraphQL ini untuk pengenalan singkat.
Kerangka kerja Tanpa Server sangat cocok untuk API GraphQL:dengan Tanpa Server, Anda tidak perlu khawatir menjalankan, mengelola, dan menskalakan server API Anda sendiri di cloud, dan Anda tidak perlu menulis skrip otomatisasi infrastruktur apa pun. Pelajari lebih lanjut tentang Tanpa Server di sini. Selain itu, Tanpa Server memberikan pengalaman pengembang agnostik vendor yang sangat baik dan komunitas yang kuat untuk membantu Anda dalam membangun aplikasi GraphQL Anda.
Banyak aplikasi dalam pengalaman kita sehari-hari berisi fitur jejaring sosial, dan fungsionalitas semacam itu benar-benar dapat mengambil manfaat dari penerapan GraphQL daripada model REST, di mana sulit untuk mengekspos struktur dengan entitas bersarang, seperti pengguna dan posting Twitter mereka. Dengan GraphQL, Anda dapat membangun titik akhir API terpadu yang memungkinkan Anda membuat kueri, menulis, dan mengedit semua entitas yang Anda perlukan menggunakan satu permintaan API.
Dalam artikel ini, kita melihat cara membangun GraphQL API sederhana dengan bantuan kerangka kerja Tanpa Server, Node.js, dan salah satu dari beberapa solusi database yang dihosting yang tersedia melalui Amazon RDS:MySQL, PostgreSQL, dan MySQL mirip Amazon Aurora.
Ikuti bersama dalam contoh repositori di GitHub ini, dan mari selami!
Membangun GraphQL API dengan backend DB relasional
Dalam proyek contoh kami, kami memutuskan untuk menggunakan ketiga database (MySQL, PostgreSQL, dan Aurora) dalam basis kode yang sama. Kami tahu, itu berlebihan bahkan untuk aplikasi produksi, tetapi kami ingin membuat Anda terpesona dengan bagaimana skala web yang kami buat.
Tapi serius, kami membebani proyek hanya untuk memastikan Anda menemukan contoh relevan yang berlaku untuk database favorit Anda. Jika Anda ingin melihat contoh dengan database lain, beri tahu kami di komentar.
Mendefinisikan skema GraphQL
Mari kita mulai dengan mendefinisikan skema GraphQL API yang ingin kita buat, yang kita lakukan di file schema.gql di root proyek kita menggunakan sintaks GraphQL. Jika Anda tidak terbiasa dengan sintaks ini, lihat contoh di halaman dokumentasi GraphQL ini.
Sebagai permulaan, kami menambahkan dua item pertama ke skema:entitas Pengguna dan entitas Post, mendefinisikannya sebagai berikut sehingga setiap Pengguna dapat memiliki beberapa entitas Post yang terkait dengannya:
ketik Pengguna {
UUID:String
Nama:String
Postingan:[Postingan]
}
ketik Posting {
UUID:String
Teks:String
}
Kita sekarang dapat melihat seperti apa entitas Pengguna dan Postingan. Nanti, kami akan memastikan kolom ini dapat disimpan langsung di database kami.
Selanjutnya, mari kita tentukan bagaimana pengguna API akan mengkueri entitas ini. Meskipun kita bisa menggunakan dua jenis GraphQL Pengguna dan Posting langsung di kueri GraphQL kita, praktik terbaiknya adalah membuat jenis input alih-alih menjaga skema tetap sederhana. Jadi kita lanjutkan dan tambahkan dua jenis input ini, satu untuk posting dan satu lagi untuk pengguna:
masukan Masukan Pengguna {
Nama:String
Postingan:[PostInput]
}
masukan Masukan Masukan {
Teks:String
}
Sekarang mari kita definisikan mutasi-operasi yang memodifikasi data yang disimpan di database kita melalui GraphQL API. Untuk ini kami membuat jenis Mutasi. Satu-satunya mutasi yang akan kita gunakan untuk saat ini adalah createUser. Karena kami menggunakan tiga database yang berbeda, kami menambahkan mutasi untuk setiap tipe database. Setiap mutasi menerima input UserInput dan mengembalikan entitas Pengguna:
Kami juga ingin menyediakan cara untuk mengkueri pengguna, jadi kami membuat tipe Kueri dengan satu kueri per tipe basis data. Setiap kueri menerima String yang merupakan UUID pengguna, mengembalikan entitas Pengguna yang berisi namanya, UUID, dan kumpulan setiap Pos terkait:
Terakhir, kami mendefinisikan skema dan menunjuk ke jenis Kueri dan Mutasi:
schema { query: Query mutation: Mutation }
Kami sekarang memiliki deskripsi lengkap untuk GraphQL API baru kami! Anda dapat melihat seluruh file di sini.
Mendefinisikan penangan untuk GraphQL API
Sekarang kita memiliki deskripsi GraphQL API kita, kita dapat menulis kode yang kita butuhkan untuk setiap query dan mutasi. Kita mulai dengan membuat file handler.js di root proyek, tepat di sebelah file schema.gql yang kita buat sebelumnya.
pekerjaan pertama handler.js adalah membaca skema:
Konstanta typeDefs sekarang memegang definisi untuk entitas GraphQL kami. Selanjutnya, kita tentukan di mana kode untuk fungsi kita akan hidup. Agar semuanya jelas, kami akan membuat file terpisah untuk setiap kueri dan mutasi:
Konstanta resolver sekarang memegang definisi untuk semua fungsi API kami. Langkah kita selanjutnya adalah membuat server GraphQL. Ingat perpustakaan graphql-yoga yang kami butuhkan di atas? Kami akan menggunakan perpustakaan itu di sini untuk membuat server GraphQL yang berfungsi dengan mudah dan cepat:
Terakhir, kita mengekspor handler GraphQL bersama dengan handler GraphQL Playground (yang akan memungkinkan kita untuk mencoba GraphQL API di browser web):
Oke, kita sudah selesai dengan file handler.js untuk saat ini. Selanjutnya:menulis kode untuk semua fungsi yang mengakses database.
Menulis kode untuk kueri dan mutasi
Kami sekarang membutuhkan kode untuk mengakses database dan untuk memberi daya pada GraphQL API kami. Di root proyek kami, kami membuat struktur berikut untuk fungsi resolver MySQL kami, dengan database lain untuk mengikuti:
Kueri umum
Di folder Common, kami mengisi file mysql.js dengan apa yang kami perlukan untuk mutasi createUser dan kueri getUser:kueri init, untuk membuat tabel untuk Pengguna dan Postingan jika belum ada; dan kueri pengguna, untuk mengembalikan data pengguna saat membuat dan membuat kueri untuk pengguna. Kami akan menggunakan ini dalam mutasi dan kueri.
Kueri init membuat tabel Pengguna dan Postingan sebagai berikut:
Kueri getUser mengembalikan pengguna dan postingan mereka:
Kedua fungsi ini diekspor; kita kemudian dapat mengaksesnya di file handler.js.
Menulis mutasi
Saatnya menulis kode untuk mutasi createUser, yang perlu menerima nama pengguna baru, serta daftar semua posting milik mereka. Untuk melakukan ini, kami membuat file resolver/Mutation/mysql_createUser.js dengan satu fungsi fungsi yang diekspor untuk mutasi:
Fungsi mutasi perlu melakukan hal-hal berikut, agar:
-
Hubungkan ke database menggunakan kredensial dalam variabel lingkungan aplikasi.
-
Masukkan pengguna ke dalam database menggunakan nama pengguna, yang diberikan sebagai masukan untuk mutasi.
-
Sisipkan juga setiap postingan yang terkait dengan pengguna, yang diberikan sebagai masukan untuk mutasi.
-
Kembalikan data pengguna yang dibuat.
Inilah cara kami mencapainya dalam kode:
Anda dapat melihat file lengkap yang mendefinisikan mutasi di sini.
Menulis kueri
Kueri getUser memiliki struktur yang mirip dengan mutasi yang baru saja kita tulis, tetapi yang ini bahkan lebih sederhana. Sekarang karena fungsi getUser berada di ruang nama Umum, kita tidak lagi memerlukan SQL khusus dalam kueri. Jadi, kami membuat file resolver/Query/mysql_getUser.js sebagai berikut:
Anda dapat melihat kueri lengkap di file ini.
Menggabungkan semuanya dalam file tanpa server.yml
Mari kita mundur selangkah. Saat ini kami memiliki yang berikut:
-
Skema API GraphQL.
-
File handler.js.
-
File untuk kueri basis data umum.
-
Sebuah file untuk setiap mutasi dan query.
Langkah terakhir adalah menghubungkan semua ini bersama-sama melalui file serverless.yml. Kami membuat serverless.yml kosong di root proyek dan mulai dengan mendefinisikan penyedia, wilayah, dan waktu proses. Kami juga menerapkan peran LambdaRole IAM (yang kami definisikan nanti di sini) ke proyek kami:
Kami kemudian mendefinisikan variabel lingkungan untuk kredensial database:
Perhatikan bahwa semua variabel merujuk ke bagian kustom, yang muncul berikutnya dan menyimpan nilai aktual untuk variabel. Perhatikan bahwa kata sandi adalah kata sandi yang buruk untuk basis data Anda dan harus diubah menjadi sesuatu yang lebih aman (mungkin p@ssw0rd ):
Apa referensi setelah Fn::GettAtt, Anda bertanya? Itu merujuk ke sumber daya basis data:
File resource/MySqlRDSInstance.yml mendefinisikan semua atribut dari instance MySQL. Anda dapat menemukan konten lengkapnya di sini.
Terakhir, dalam file serverless.yml kita mendefinisikan dua fungsi, graphql dan taman bermain. Fungsi graphql akan menangani semua permintaan API, dan titik akhir taman bermain akan membuat instance GraphQL Playground untuk kami, yang merupakan cara yang bagus untuk mencoba API GraphQL kami di browser web:
Sekarang dukungan MySQL untuk aplikasi kita telah selesai!
Anda dapat menemukan konten lengkap file serverless.yml di sini.
Menambahkan dukungan Aurora dan PostgreSQL
Kami telah membuat semua struktur yang kami butuhkan untuk mendukung database lain dalam proyek ini. Untuk menambahkan dukungan untuk Aurora dan Postgres, kita hanya perlu mendefinisikan kode untuk mutasi dan kuerinya, yang kita lakukan sebagai berikut:
-
Tambahkan file kueri umum untuk Aurora dan Postgres.
-
Tambahkan mutasi createUser untuk kedua database.
-
Tambahkan kueri getUser untuk kedua database.
-
Tambahkan konfigurasi di file serverless.yml untuk semua variabel lingkungan dan sumber daya yang diperlukan untuk kedua database.
Pada titik ini, kami memiliki semua yang kami butuhkan untuk menerapkan GraphQL API kami, yang didukung oleh MySQL, Aurora, dan PostgreSQL.
Menerapkan dan menguji GraphQL API
Penerapan GraphQL API kami sederhana.
-
Pertama kita jalankan npm install untuk menempatkan dependensi kita.
-
Kemudian kami menjalankan npm run deploy, yang menyiapkan semua variabel lingkungan kami dan melakukan penerapan.
-
Di bawah tenda, perintah ini menjalankan penerapan tanpa server menggunakan lingkungan yang tepat.
Itu dia! Dalam output dari langkah penerapan, kita akan melihat titik akhir URL untuk aplikasi yang diterapkan. Kami dapat mengeluarkan permintaan POST ke GraphQL API kami menggunakan URL ini, dan Playground kami (yang akan kami mainkan dalam sedetik) tersedia menggunakan GET terhadap URL yang sama.
Mencoba API di GraphQL Playground
GraphQL Playground, yang Anda lihat saat mengunjungi URL tersebut di browser, adalah cara yang bagus untuk mencoba API kami.
Mari kita buat pengguna dengan menjalankan mutasi berikut:
mutation { mysql_createUser( input: { Name: "Cicero" Posts: [ { Text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit." } { Text: "Proin consequat mauris orci, ut consequat purus efficitur vel." } ] } ) { Name UUID } }
Dalam mutasi ini, kami memanggil mysql_createUser API, menyediakan teks posting pengguna baru, dan menunjukkan bahwa kami ingin mendapatkan nama pengguna dan UUID kembali sebagai tanggapan.
Rekatkan teks di atas ke sisi kiri Playground dan klik tombol Play. Di sebelah kanan, Anda akan melihat output kueri:
Sekarang mari kita kueri untuk pengguna ini:
query { mysql_getUser(uuid: "f5593682-6bf1-466a-967d-98c7e9da844b") { Name UUID } }
Ini memberi kami kembali nama dan UUID pengguna yang baru saja kami buat. Rapi!
Kita dapat melakukan hal yang sama dengan backend lainnya, PostgreSQL dan Aurora. Untuk itu, kita hanya perlu mengganti nama-nama mutasi dengan postgres_createUser atau aurora_createUser, dan query dengan postgres_getUser atau aurora_getUser. Cobalah sendiri! (Perhatikan bahwa pengguna tidak disinkronkan antar database, jadi Anda hanya dapat membuat kueri untuk pengguna yang telah Anda buat di setiap database tertentu.)
Membandingkan implementasi MySQL, PostgreSQL, dan Aurora
Untuk memulainya, mutasi dan kueri terlihat sama persis di Aurora dan MySQL, karena Aurora kompatibel dengan MySQL. Dan hanya ada sedikit perbedaan kode antara keduanya dan implementasi Postgres.
Faktanya, untuk kasus penggunaan sederhana, perbedaan terbesar antara ketiga database kami adalah Aurora hanya tersedia sebagai cluster. Konfigurasi Aurora terkecil yang tersedia masih mencakup satu replika baca-saja dan satu tulis, jadi kami memerlukan konfigurasi yang dikelompokkan bahkan untuk penerapan Aurora dasar ini.
Aurora menawarkan kinerja yang lebih cepat daripada MySQL dan PostgreSQL, terutama karena optimasi SSD yang dibuat Amazon untuk mesin database. Seiring pertumbuhan proyek Anda, Anda mungkin akan menemukan bahwa Aurora menawarkan peningkatan skalabilitas basis data, perawatan yang lebih mudah, dan keandalan yang lebih baik dibandingkan dengan konfigurasi default MySQL dan PostgreSQL. Namun Anda juga dapat melakukan beberapa peningkatan ini pada MySQL dan PostgreSQL jika Anda menyetel database dan menambahkan replikasi.
Untuk proyek pengujian dan taman bermain, kami merekomendasikan MySQL atau PostgreSQL. Ini dapat berjalan pada instans db.t2.micro RDS, yang merupakan bagian dari tingkat gratis AWS. Aurora saat ini tidak menawarkan instans db.t2.micro, jadi Anda akan membayar sedikit lebih mahal untuk menggunakan Aurora untuk proyek pengujian ini.
Catatan penting terakhir
Ingatlah untuk menghapus penerapan Tanpa Server Anda setelah Anda selesai mencoba GraphQL API sehingga Anda tidak terus membayar untuk sumber daya database yang tidak lagi Anda gunakan.
Anda dapat menghapus tumpukan yang dibuat dalam contoh ini dengan menjalankan npm run remove di root proyek.
Selamat bereksperimen!
Ringkasan
Dalam artikel ini kami memandu Anda dalam membuat GraphQL API sederhana, menggunakan tiga database berbeda sekaligus; meskipun ini bukan sesuatu yang pernah Anda lakukan dalam kenyataan, ini memungkinkan kami untuk membandingkan implementasi sederhana dari database Aurora, MySQL, dan PostgreSQL. Kami melihat bahwa implementasi untuk ketiga database kurang lebih sama dalam kasus sederhana kami, kecuali perbedaan kecil dalam sintaks dan konfigurasi penerapan.
Anda dapat menemukan contoh proyek lengkap yang telah kami gunakan di repo GitHub ini. Cara termudah untuk bereksperimen dengan proyek ini adalah dengan mengkloning repo dan menerapkannya dari mesin Anda menggunakan npm run deploy.
Untuk contoh GraphQL API lainnya menggunakan Serverless, lihat repo serverless-graphql.
Jika Anda ingin mempelajari lebih lanjut tentang menjalankan API GraphQL Tanpa Server dalam skala besar, Anda dapat menikmati seri artikel kami “Menjalankan titik akhir GraphQL yang dapat diskalakan &andal dengan Tanpa Server”
Mungkin GraphQL bukan masalah Anda, dan Anda lebih suka menggunakan REST API? Kami siap membantu Anda:lihat entri blog ini untuk beberapa contoh.
pertanyaan? Komentari postingan ini, atau buat diskusi di forum kami.
Awalnya diterbitkan di https://www.serverless.com.