Rust पर GraphQL API का परिचय
आधुनिक वेब डेवलपमेंट में डेटा के साथ काम करते समय उच्च प्रदर्शन और लचीलेपन की आवश्यकता होती है। Rust एक सिस्टम प्रोग्रामिंग भाषा है, जो अपनी गति और मेमोरी सुरक्षा के लिए जानी जाती है, और GraphQL एक शक्तिशाली क्वेरी भाषा है, जो क्लाइंट को केवल आवश्यक डेटा प्राप्त करने की अनुमति देती है। इन तकनीकों का संयोजन अविश्वसनीय रूप से तेज़ और सुविधाजनक API प्रदान करता है।
इस ट्यूटोरियल में, हम लोकप्रिय क्रेट Juniper (GraphQL को लागू करने के लिए) और Actix-web (HTTP सर्वर के लिए) का उपयोग करके Rust पर एक पूर्ण GraphQL API बनाएंगे। आप सीखेंगे कि प्रोजेक्ट को कैसे सेट अप करें, स्कीमा को परिभाषित करें, रिज़ॉल्वर को लागू करें और अनुरोधों को संसाधित करें।
यह लेख उन डेवलपर्स के लिए है जो पहले से Rust की मूल बातें और वेब API की बुनियादी अवधारणाओं से परिचित हैं। हम Rust 2021 edition और नवीनतम स्थिर निर्भरताओं का उपयोग करेंगे।
चरण 1: प्रोजेक्ट और निर्भरताएँ सेट अप करना
एक नया Rust प्रोजेक्ट बनाकर शुरू करें। टर्मिनल खोलें और निम्नलिखित चलाएँ:
cargo new graphql-rust-apicd graphql-rust-apiफिर Cargo.toml फ़ाइल खोलें और निम्नलिखित निर्भरताएँ जोड़ें:
[dependencies]actix-web = "4"actix-rt = "2"juniper = "0.16"serde = { version = "1.0", features = ["derive"] }tokio = { version = "1", features = ["full"] }- actix-web — Rust के लिए एक एसिंक्रोनस वेब फ्रेमवर्क।
- juniper — Rust पर GraphQL को लागू करने के लिए लाइब्रेरी।
- serde — डेटा के सीरियलाइज़ेशन/डीसीरियलाइज़ेशन के लिए।
- tokio — एसिंक्रोनस रनटाइम, Actix के लिए आवश्यक।
निर्भरताएँ अपडेट करने के बाद, यह सुनिश्चित करने के लिए cargo build चलाएँ कि सब कुछ सही ढंग से स्थापित हो रहा है।
चरण 2: डेटा मॉडल और GraphQL स्कीमा को परिभाषित करना
उदाहरण के लिए, हम फ़ील्ड के साथ एक सरल "पुस्तक" मॉडल बनाएंगे: id, शीर्षक, लेखक और प्रकाशन वर्ष। src/models.rs फ़ाइल बनाएँ:
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct Book { pub id: i32, pub title: String, pub author: String, pub year: i32,}अब GraphQL स्कीमा को परिभाषित करें। src/graphql.rs बनाएँ:
use juniper::{FieldResult, GraphQLObject, GraphQLInputObject, RootNode};use crate::models::Book;
// पुस्तक के लिए GraphQL प्रकार (आउटपुट)#[derive(GraphQLObject)]#[graphql(description = "पुस्तक")]pub struct BookGQL { pub id: i32, pub title: String, pub author: String, pub year: i32,}
// नई पुस्तक बनाने के लिए इनपुट प्रकार#[derive(GraphQLInputObject)]#[graphql(description = "नई पुस्तक के लिए इनपुट डेटा")]pub struct NewBook { pub title: String, pub author: String, pub year: i32,}
// मेमोरी में "डेटाबेस"use std::sync::Mutex;lazy_static::lazy_static! { static ref BOOKS: Mutex<Vec<Book>> = Mutex::new(vec![ Book { id: 1, title: "Rust इन एक्शन".to_string(), author: "टिम मैकनामारा".to_string(), year: 2021 }, Book { id: 2, title: "Rust प्रोग्रामिंग".to_string(), author: "जिम ब्लैंडी".to_string(), year: 2020 }, ]);}
// रूट क्वेरी (Query)pub struct QueryRoot;
#[juniper::object]impl QueryRoot { fn books() -> FieldResult<Vec<BookGQL>> { let books = BOOKS.lock().unwrap(); Ok(books.iter().map(|b| BookGQL { id: b.id, title: b.title.clone(), author: b.author.clone(), year: b.year, }).collect()) }
fn book(id: i32) -> FieldResult<BookGQL> { let books = BOOKS.lock().unwrap(); let book = books.iter().find(|b| b.id == id) .ok_or_else(|| juniper::FieldError::new("पुस्तक नहीं मिली", graphql_value!({"code": "NOT_FOUND"})))?; Ok(BookGQL { id: book.id,