Cara Membuat API GraphQL Node.js Aman

Diterbitkan: 2022-03-11

Pada artikel ini, kami bertujuan untuk menyajikan panduan singkat tentang cara membuat Node.js GraphQL API yang aman.

Beberapa pertanyaan yang mungkin muncul di benak mungkin adalah:

  • Apa tujuan menggunakan GraphQL API?
  • Apa itu GraphQL API?
  • Apa itu kueri GraphQL?
  • Apa manfaat GraphQL?
  • Apakah GraphQL lebih baik daripada REST?
  • Mengapa kami menggunakan Node.js?

Semua itu adalah pertanyaan yang valid, tetapi sebelum menjawabnya, kita harus menyelami gambaran singkat tentang keadaan pengembangan web saat ini:

  • Hampir setiap solusi yang Anda temukan saat ini menggunakan beberapa jenis antarmuka pemrograman aplikasi (API).
  • Bahkan jika Anda hanya menggunakan jejaring sosial, seperti Facebook atau Instagram, Anda masih terhubung ke front-end yang menggunakan API.
  • Jika Anda penasaran, Anda akan menemukan bahwa hampir semua layanan hiburan online menggunakan jenis API yang berbeda, termasuk layanan seperti Netflix, Spotify, dan YouTube.

Di hampir setiap skenario, Anda akan menemukan API yang tidak perlu Anda ketahui secara detail, misalnya, Anda tidak perlu tahu cara pembuatannya, dan Anda tidak perlu menggunakan teknologi yang sama seperti sebelumnya. dapat mengintegrasikannya ke dalam sistem Anda sendiri. API yang disediakan memungkinkan Anda menawarkan cara untuk berkomunikasi antar layanan dalam standar umum yang dapat dikomunikasikan oleh layanan dan klien tanpa harus bergantung pada tumpukan teknologi tertentu.

Dengan API yang terstruktur dengan baik, dimungkinkan untuk memiliki API yang solid, dapat dipelihara, dan dapat diskalakan yang dapat melayani berbagai jenis klien dan aplikasi front-end.

Yang Mengatakan, Apa itu GraphQL API?

GraphQL adalah bahasa kueri untuk API, dikembangkan untuk penggunaan internal di Facebook dan diterbitkan untuk penggunaan umum pada tahun 2015. Ini mendukung membaca, menulis, dan pembaruan waktu nyata. Ini juga open source, dan biasanya dibandingkan dengan REST dan arsitektur lainnya. Hal ini, secara singkat, didasarkan pada:

  • GraphQL Query - Ini memungkinkan klien untuk membaca dan memanipulasi bagaimana data harus diterima.
  • Mutasi GraphQL - Ini adalah cara menulis data di server. Ini adalah konvensi GraphQL tentang cara menulis data ke dalam sistem.

Meskipun artikel ini seharusnya mendemonstrasikan sederhana, namun skenario dunia nyata tentang cara membangun dan menggunakan GraphQL API, kami tidak akan memberikan pengenalan rinci ke GraphQL. Alasannya sederhana, karena tim GraphQL menyediakan dokumentasi yang komprehensif dan mencantumkan beberapa praktik terbaik dalam Pengantar GraphQL mereka.

Apa itu Kueri GraphQL?

Seperti yang dijelaskan sebelumnya, kueri adalah cara klien dapat membaca dan memanipulasi data dari API. Anda dapat meneruskan jenis objek dan memilih jenis bidang yang ingin Anda terima kembali. Sebuah query sederhana akan seperti berikut:

 query{ users{ firstName, lastName } }

Dalam kueri ini, kami mencoba menjangkau semua pengguna dari skema pengguna kami tetapi hanya menerima firstName dan lastName . Hasil dari kueri ini akan seperti, misalnya:

 { "data": { "users": [ { "firstName": "Marcos", "lastName": "Silva" }, { "firstName": "Paulo", "lastName": "Silva" } ] } }

Ini cukup sederhana untuk penggunaan klien.

Apa Tujuan Menggunakan GraphQL API?

Tujuan pembuatan API adalah kemampuan untuk memiliki perangkat lunak sebagai layanan yang dapat diintegrasikan dengan layanan eksternal lainnya. Bahkan jika aplikasi Anda digunakan oleh satu front-end, Anda dapat menganggap front-end ini sebagai layanan eksternal, dan untuk itu, Anda akan dapat bekerja di proyek yang berbeda ketika komunikasi antara keduanya disediakan melalui API.

Jika Anda bekerja dalam tim besar, itu dapat dipecah untuk membuat tim front-end dan back-end, memungkinkan keduanya menggunakan teknologi yang sama dan membuat pekerjaan mereka lebih mudah. Saat merancang API, penting untuk memilih yang lebih cocok untuk proyek dan apa yang membawa Anda lebih dekat ke solusi yang Anda inginkan.

Pada artikel ini, kita akan berfokus pada kerangka untuk membangun API yang menggunakan GraphQL.

Apakah GraphQL Lebih Baik Dari REST?

Ini mungkin sedikit merepotkan, tetapi saya tidak dapat menahannya: Itu tergantung .

GraphQL adalah pendekatan yang sangat cocok dengan beberapa skenario. REST adalah pendekatan arsitektur yang terbukti dalam beberapa skenario juga. Saat ini, ada banyak sekali artikel yang menjelaskan mengapa yang satu lebih baik dari yang lain atau mengapa Anda harus menggunakan REST saja daripada GraphQL. Dan juga, banyak cara Anda dapat menggunakan GraphQL secara internal dan tetap mempertahankan titik akhir API sebagai arsitektur berbasis REST.

Panduan terbaik adalah mengetahui manfaat dari setiap pendekatan, menganalisis solusi yang Anda buat, mengevaluasi seberapa nyaman tim Anda bekerja dengan solusi tersebut, dan menilai apakah Anda dapat memandu tim Anda untuk belajar dan bangkit atau tidak. kecepatan cepat sebelum memilih antara pendekatan.

Artikel ini lebih merupakan panduan praktis daripada perbandingan subjektif GraphQL dan REST. Jika Anda ingin membaca perbandingan detail keduanya, saya sarankan Anda membaca artikel kami yang lain, GraphQL vs. REST - A GraphQL Tutorial.

Dalam artikel hari ini, kita akan fokus membuat GraphQL API menggunakan Node.js.

Mengapa Kami Menggunakan Node.js?

GraphQL memiliki beberapa perpustakaan berbeda yang dapat Anda gunakan. Untuk tujuan artikel ini, kami memutuskan untuk menggunakan JavaScript dengan Node.js karena penggunaannya yang luas dan fakta bahwa Node.js memungkinkan pengembang untuk menggunakan sintaks front-end yang sudah dikenal untuk pengembangan sisi server.

Juga berguna untuk membandingkan pendekatan kami dengan API berbasis REST, mirip dengan yang ditunjukkan dalam artikel Blog Toptal Engineering lainnya: Membuat API REST Aman di Node.js. Artikel ini juga menampilkan penggunaan Node.js dengan Express untuk mengembangkan kerangka REST API yang memungkinkan Anda membandingkan beberapa perbedaan antara kedua pendekatan ini. Node.js juga dirancang dengan aplikasi jaringan yang dapat diskalakan, komunitas global, dan beberapa pustaka sumber terbuka yang dapat Anda temukan di situs web npm.

Kali ini, kami akan menunjukkan cara membangun kerangka API dengan GraphQL, Node.js, dan Express!

Tutorial GraphQL langsung

Seperti yang dijelaskan sebelumnya, kami akan membangun ide kerangka untuk GraphQL API, dan Anda perlu mengetahui dasar-dasar Node.js dan Express sebelum melanjutkan. Kode sumber proyek yang dibuat untuk contoh GraphQL ini tersedia di sini.

Kami akan menangani dua jenis sumber daya:

  • Pengguna, yang akan kami tangani CRUD dasar.
  • Produk, yang kami akan memiliki sedikit detail untuk menunjukkan lebih banyak kekuatan GraphQL.

Pengguna akan berisi struktur berikut:

  • pengenal
  • nama depan
  • nama keluarga
  • surel
  • kata sandi
  • izinLevel

Produk akan berisi struktur berikut:

  • pengenal
  • nama
  • keterangan
  • harga

Adapun standar pengkodean, kita akan menggunakan TypeScript untuk proyek ini. Di file sumber, Anda akan dapat mengonfigurasi semuanya untuk memulai pengkodean dengan TypeScript.

Ayo Kode!

Pertama-tama, pastikan Anda menginstal Node.js versi terbaru. Pada saat publikasi, versi saat ini adalah 10.15.3, menurut Nodejs.org.

Inisialisasi Proyek

Mari kita mulai di folder baru yang bisa kita beri nama node-graphql . Di sana, kita dapat membuka terminal atau konsol Git CLI dan memulai keajaiban menggunakan perintah berikut: npm init .

Mengonfigurasi Dependensi dan TypeScript kami

Untuk mempercepat proses, mengganti package.json Anda dengan yang berikut di repositori Git kami harus berisi semua dependensi yang diperlukan:

 { "name": "node-graphql", "version": "1.0.0", "description": "", "main": "dist/index.js", "scripts": { "tsc": "tsc", "start": "npm run tsc && node ./build/app.js" }, "author": "", "license": "ISC", "dependencies": { "@types/express": "^4.16.1", "@types/express-graphql": "^0.6.2", "@types/graphql": "^14.0.7", "express": "^4.16.4", "express-graphql": "^0.7.1", "graphql": "^14.1.1", "graphql-tools": "^4.0.4" }, "devDependencies": { "tslint": "^5.14.0", "typescript": "^3.3.4000" } }

Dengan package.json yang diperbarui, tekan saja terminal lagi dan gunakan: npm install . Ini akan menginstal semua dependensi yang diperlukan untuk menjalankan GraphQL API ini di dalam Node.js dan Express.

Bagian selanjutnya adalah mengkonfigurasi mode TypeScript kami. Kami membutuhkan file bernama tsconfig.json di folder root kami dengan yang berikut:

 { "compilerOptions": { "target": "ES2016", "module": "commonjs", "outDir": "./build", "strict": true, "esModuleInterop": true } }

Logika kode untuk konfigurasi ini akan ada di folder aplikasi. Di sana kita dapat membuat file app.ts dan untuk pengujian dasar tambahkan kode berikut di sana:

 console.log('Hello Graphql Node API tutorial');

Dengan konfigurasi kami, kami sekarang dapat menjalankan npm start dan menunggu build dan dapat menguji apakah semuanya berfungsi dengan baik. Di konsol terminal Anda, Anda akan melihat “tutorial Hello GraphQL Node API” kami. Di adegan belakang, konfigurasi pada dasarnya mengkompilasi kode TypeScript ke dalam JavaScript murni dan kemudian mengeksekusi build kita di folder build .

Sekarang mari kita konfigurasikan kerangka dasar untuk GraphQL API kita. Untuk memulai proyek kami, kami akan menambahkan tiga impor dasar:

  • cepat
  • Express-graphql
  • Graphql-alat

Mari kita mulai menyatukan semuanya:

 import express from 'express'; import graphqlHTTP from 'express-graphql'; import {makeExecutableSchema} from 'graphql-tools';

Sekarang kita harus bisa mulai membuat kode sedikit. Langkah selanjutnya adalah menangani aplikasi kami di Express dan konfigurasi GraphQL dasar seperti:

 import express from 'express'; import graphqlHTTP from 'express-graphql'; import {makeExecutableSchema} from 'graphql-tools'; const app: express.Application = express(); const port = 3000; let typeDefs: any = [` type Query { hello: String } type Mutation { hello(message: String) : String } `]; let helloMessage: String = 'World!'; let resolvers = { Query: { hello: () => helloMessage }, Mutation: { hello: (_: any, helloData: any) => { helloMessage = helloData.message; return helloMessage; } } }; app.use( '/graphql', graphqlHTTP({ schema: makeExecutableSchema({typeDefs, resolvers}), graphiql: true }) ); app.listen(port, () => console.log(`Node Graphql API listening on port ${port}!`));

Apa yang kami lakukan adalah:

  • Mengaktifkan port 3000 untuk aplikasi server Express kami.
  • Menentukan kueri dan mutasi mana yang ingin kita gunakan sebagai contoh cepat.
  • Mendefinisikan bagaimana kueri dan mutasi akan bekerja.

Oke, tapi apa yang terjadi untuk typeDefs dan resolver, serta kaitannya dengan kueri dan mutasi?

  • typeDefs - Definisi skema kami tentang apa yang dapat kami harapkan dari kueri dan mutasi.
  • Penyelesai - Alih-alih ekspektasi bidang atau parameter yang diperlukan, di sini kami mendefinisikan fungsi dan perilaku tentang bagaimana kueri dan mutasi akan bekerja.
  • Query - "Dapatkan" yang ingin kita baca dari server.
  • Mutasi - Permintaan kami yang akan memengaruhi data apa pun yang kami miliki di server kami sendiri.

Sekarang, mari kita jalankan npm start lagi untuk melihat apa yang kita miliki di sana. Kami berharap aplikasi akan berjalan dengan pesan berikut: Node Graphql API mendengarkan pada port 3000!

Kami sekarang dapat mencoba untuk menanyakan dan menguji GraphQL API di server kami sendiri melalui: http://localhost:3000/graphql

Tutorial GraphQL: uji server

Bagus, sekarang kita bisa menulis kueri pertama kita sendiri yang didefinisikan sebagai "halo."

Tutorial GraphQL: permintaan pertama

Perhatikan bahwa cara kami mendefinisikannya di typeDefs , halaman dapat membantu kami membuat kueri.

Itu bagus, tapi bagaimana kita bisa mengubah nilainya? Mutasi!

Sekarang, mari kita lihat apa yang terjadi ketika kita mengubah nilai dalam memori kita dengan sebuah mutasi:

Tutorial GraphQL: demostrasi mutasi

Sekarang kita dapat melakukan operasi CRUD dasar dengan GraphQL Node.js API. Mari kita maju dengan kode kita sekarang.

Produk

Untuk produk, kami akan menggunakan modul yang disebut produk. Sebagai upaya untuk menyederhanakan artikel ini, kami akan menggunakan database di dalam memori hanya untuk demonstrasi. Kami akan menentukan model dan layanan untuk mengelola produk.

Model kami akan didasarkan sebagai berikut:

 export class Product { private id: Number = 0; private name: String = ''; private description: String = ''; private price: Number = 0; constructor(productId: Number, productName: String, productDescription: String, price: Number) { this.id = productId; this.name = productName; this.description = productDescription; this.price = price; } }

Layanan yang akan berkomunikasi dengan GraphQL akan didefinisikan sebagai:

 export class ProductsService { public products: any = []; configTypeDefs() { let typeDefs = ` type Product { name: String, description: String, id: Int, price: Int } `; typeDefs += ` extend type Query { products: [Product] } `; typeDefs += ` extend type Mutation { product(name:String, id:Int, description: String, price: Int): Product! }`; return typeDefs; } configResolvers(resolvers: any) { resolvers.Query.products = () => { return this.products; }; resolvers.Mutation.product = (_: any, product: any) => { this.products.push(product); return product; }; } }

Pengguna

Untuk pengguna, kami akan mengikuti struktur yang sama dengan modul produk. Kami akan memiliki model dan layanan untuk pengguna. Model akan didefinisikan sebagai:

 export class User { private id: Number = 0; private firstName: String = ''; private lastName: String = ''; private email: String = ''; private password: String = ''; private permissionLevel: Number = 1; constructor(id: Number, firstName: String, lastName: String, email: String, password: String, permissionLevel: Number) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.email = email; this.password = password; this.permissionLevel = permissionLevel; } }

Sementara itu, layanan kami akan seperti:

 const crypto = require('crypto'); export class UsersService { public users: any = []; configTypeDefs() { let typeDefs = ` type User { firstName: String, lastName: String, id: Int, password: String, permissionLevel: Int, email: String } `; typeDefs += ` extend type Query { users: [User] } `; typeDefs += ` extend type Mutation { user(firstName:String, lastName: String, password: String, permissionLevel: Int, email: String, id:Int): User! }`; return typeDefs; } configResolvers(resolvers: any) { resolvers.Query.users = () => { return this.users; }; resolvers.Mutation.user = (_: any, user: any) => { let salt = crypto.randomBytes(16).toString('base64'); let hash = crypto.createHmac('sha512', salt).update(user.password).digest("base64"); user.password = hash; this.users.push(user); return user; }; } }

Sebagai pengingat, kode sumber tersedia untuk digunakan dari tautan ini.

Sekarang kita bisa bermain dan menguji kode kita. Mari kita jalankan npm start . Kita akan menjalankan server pada port 3000. Sekarang kita dapat mengakses GraphQL untuk pengujian di http://localhost:3000/graphql.

Mari kita coba mutasi untuk menambahkan item ke daftar produk kami:

Demonstrasi mutasi Node.js GraphQL

Untuk menguji apakah itu berhasil, kita sekarang akan menggunakan kueri untuk produk, tetapi hanya menerima id , name , dan price :

 query{ products{ id, name, price } } The response will be: { "data": { "products": [ { "id": 100, "name": "My amazing product", "price": 400 } ] } }

Dan hanya itu; produk berfungsi sesuai harapan. Sekarang kita bisa bermain dan mengganti ladang jika kita mau. Anda dapat mencoba menambahkan deskripsi:

 query{ products{ id, name, description, price } }

Sekarang kita dapat memiliki deskripsi produk kita. Mari kita coba pengguna sekarang.

 mutation{ user(id:200, firstName:"Marcos", lastName:"Silva", password:"amaz1ingP4ss", permissionLevel:9, email:"[email protected]") { id } }

Dan kueri akan seperti:

 query{ users{ id, firstName, lastName, password, email } }

Dengan tanggapan seperti:

 { "data": { "users": [ { "id": 200, "firstName": "Marcos", "lastName": "Silva", "password": "kpj6Mq0tGChGbZ+BT9Nw6RMCLReZEPPyBCaUS3X23lZwCCp1Ogb94/oqJlya0xOBdgEbUwqRSuZRjZGhCzLdeQ==", "email": "[email protected]" } ] } }

Dan sekarang kerangka GraphQL kami sudah siap! Ada banyak langkah dari sini menuju API yang berguna dan berfungsi penuh, tetapi inti dasarnya sekarang telah ditetapkan.

Ringkasan dan Pikiran Akhir

Bahkan memotong tepi untuk mempersingkat, artikel ini cukup besar dengan banyak informasi dasar mengenai pengembangan GraphQL Node.js API.

Mari kita tinjau apa yang telah kita bahas sejauh ini:

  • Penggunaan Node.js dengan Express dan GraphQL untuk membangun GraphQL API;
  • Penggunaan GraphQL dasar;
  • Penggunaan dasar kueri dan mutasi;
  • Pendekatan dasar untuk membuat modul untuk proyek Anda;
  • Menguji API GraphQL kami;

Untuk lebih fokus pada sisi pengembangan, kami menghindari beberapa item penting yang secara singkat dapat diringkas sebagai berikut:

  • Validasi untuk item baru;
  • Menangani kesalahan dengan benar dengan layanan kesalahan umum;
  • Memvalidasi bidang yang dapat digunakan pengguna pada setiap permintaan dengan layanan umum;
  • Tambahkan pencegat JWT untuk mengamankan API;
  • Tangani hash kata sandi dengan pendekatan yang lebih efektif;
  • Tambahkan tes unit dan integrasi;

Ingatlah bahwa kami memiliki kode sumber lengkap di tautan Git ini. Jangan ragu untuk menggunakan, bercabang, membuka masalah, membuat permintaan tarik, dan memainkannya! Harap dicatat bahwa semua standar dan saran yang dibuat dalam artikel ini tidak diukir di atas batu.

Ini hanyalah salah satu dari banyak pendekatan yang dapat digunakan untuk mulai mendesain GraphQL API Anda sendiri. Selain itu, pastikan untuk membaca dan menjelajahi GraphQL lebih detail, mempelajari apa yang ditawarkannya dan bagaimana hal itu dapat membuat API Anda menjadi lebih baik.