গ্রাফকিউএল (GraphQL)-এ Resolvers হল এমন ফাংশন যা কুয়েরি বা মিউটেশনের অনুরোধে সার্ভারের ডেটা ফেরত আনতে সহায়ক। এটি গ্রাফকিউএল স্কিমার অংশ হিসেবে কাজ করে এবং মূলত গ্রাফকিউএল API-তে ডেটা রিট্রিভ বা ম্যানিপুলেট করার জন্য ব্যবহৃত হয়। প্রতিটি কুয়েরি বা মিউটেশনের জন্য একটি রেজোলভার (resolver) নির্ধারণ করা হয়, যা সেই কুয়েরি বা মিউটেশনের জন্য প্রয়োজনীয় ডেটা প্রদান করে।
Resolvers কী?
Resolvers হল ফাংশন যা কুয়েরি বা মিউটেশনের জন্য ডেটা ফিরিয়ে আনে। যখন ক্লায়েন্ট একটি কুয়েরি বা মিউটেশন পাঠায়, সার্ভার সেই কুয়েরির জন্য নির্দিষ্ট রেজোলভার ফাংশন চালায় এবং এর মাধ্যমে প্রাপ্ত ডেটা ক্লায়েন্টের কাছে ফিরিয়ে দেওয়া হয়। প্রতিটি কুয়েরি বা মিউটেশনের জন্য আলাদা রেজোলভার থাকতে পারে, যা কুয়েরির কাঠামো অনুসারে ডেটা সংগ্রহ করতে সাহায্য করে।
Resolvers এর গঠন
একটি সাধারণ রেজোলভার ফাংশন নিম্নলিখিত অংশগুলি নিয়ে গঠিত থাকে:
- Parent (প্যারেন্ট):
পূর্ববর্তী ফাংশন বা রেজোলভার থেকে প্রাপ্ত তথ্য, যদি কোনো নেস্টেড কুয়েরি থাকে। - Arguments (আর্গুমেন্টস):
কুয়েরি বা মিউটেশন থেকে প্রাপ্ত আর্গুমেন্ট। উদাহরণস্বরূপ, ইউজার ID বা নাম। - Context (কন্টেক্সট):
রেজোলভার ফাংশনটি চলাকালীন সময়ে সার্ভার বা অ্যাপ্লিকেশনের জন্য একটি সাধারণ কনটেক্সট প্রদান করে, যেমন লগিং বা ইউজার সেশনের তথ্য। - Info (ইনফো):
কুয়েরির মধ্যে কোন ফিল্ড চাওয়া হয়েছে এবং এটি কীভাবে ট্রান্সফর্ম হবে, এর বিস্তারিত তথ্য।
Resolvers এর উদাহরণ
ধরা যাক, আমাদের একটি User ডেটা ফেচিং করতে হবে। এখানে একটি সাধারণ রেজোলভার সেটআপ দেওয়া হলো:
- GraphQL স্কিমা:
type User {
id: ID
name: String
email: String
}
type Query {
getUser(id: ID!): User
}
- Resolvers:
const resolvers = {
Query: {
getUser: (parent, args, context, info) => {
const { id } = args;
// এখানে ডেটাবেস বা অন্য কোনো সোর্স থেকে ইউজারকে খুঁজে বের করা হবে
const user = {
id,
name: "John Doe",
email: "john.doe@example.com"
};
return user;
}
}
};
এখানে:
- getUser একটি কুয়েরি ফাংশন যা ইউজারের তথ্য ফেরত আনে।
- args-এর মাধ্যমে ইউজারের ID পাওয়া যায় এবং সেই অনুযায়ী ডেটা ফেরত আসে।
Data Fetching (ডেটা ফেচিং)
গ্রাফকিউএল-এ Data Fetching হল ডেটাবেস বা অন্য যেকোনো সোর্স থেকে প্রয়োজনীয় ডেটা সংগ্রহ করার প্রক্রিয়া। এটি সাধারণত রেজোলভার ফাংশনগুলির মাধ্যমে পরিচালিত হয়। ডেটা ফেচিংয়ের প্রক্রিয়া নিম্নরূপ:
REST API এর মাধ্যমে ডেটা ফেচিং: গ্রাফকিউএল রেজোলভার ফাংশনগুলিতে যদি আপনার REST API থেকে ডেটা ফেচ করার প্রয়োজন হয়, তবে আপনি সাধারণভাবে HTTP রিকোয়েস্ট পাঠিয়ে ডেটা ফিরিয়ে আনতে পারেন। উদাহরণস্বরূপ,
axiosবাfetchব্যবহার করে।উদাহরণ:
const resolvers = { Query: { getUser: async (parent, args) => { const { id } = args; const response = await fetch(`https://api.example.com/users/${id}`); const user = await response.json(); return user; } } };ডেটাবেস থেকে ডেটা ফেচিং: গ্রাফকিউএল রেজোলভার ডেটাবেসের সাথে ইন্টিগ্রেট হয়ে ডেটা ফেচ করতে সক্ষম। ধরুন, আপনি MongoDB বা MySQL থেকে ডেটা আনার জন্য কোড লেখেন।
উদাহরণ (MongoDB):
const resolvers = { Query: { getUser: async (parent, args) => { const { id } = args; const user = await UserModel.findById(id); return user; } } };- ফাইল বা কাস্টম সোর্স থেকে ডেটা ফেচিং: আপনি যদি কাস্টম সোর্স থেকে ডেটা সংগ্রহ করতে চান, যেমন ফাইল সিস্টেম বা একটি থার্ড-পার্টি API, তাহলে আপনি সরাসরি রেজোলভার ফাংশন থেকে সেই সোর্সে কোড লিখে ডেটা ফেচ করতে পারবেন।
Resolvers এবং Data Fetching-এ গুরুত্বপূর্ণ বিষয়
নেস্টেড রেজোলভারস: গ্রাফকিউএল কুয়েরিতে নেস্টেড রেজোলভার হতে পারে, অর্থাৎ একটি কুয়েরি ফাংশনের মধ্যে আরেকটি কুয়েরি হতে পারে। উদাহরণস্বরূপ, যদি আপনি ইউজারের পোস্টের তথ্য চান, তাহলে আপনাকে ইউজারের রেজোলভার ফাংশন এবং পোস্টের রেজোলভার ফাংশন আলাদা আলাদা নির্ধারণ করতে হবে।
উদাহরণ:
type User { id: ID name: String posts: [Post] } type Post { id: ID title: String content: String } type Query { getUser(id: ID!): User }Resolvers:
const resolvers = { Query: { getUser: (parent, args) => { const { id } = args; // ইউজারের তথ্য ফেচ করা হবে return { id, name: "John Doe" }; } }, User: { posts: (parent) => { // এখানে ইউজারের পোস্টগুলি ফেচ করা হবে return [ { id: "1", title: "Post 1", content: "Content of post 1" }, { id: "2", title: "Post 2", content: "Content of post 2" } ]; } } };
সারাংশ
Resolvers হল গ্রাফকিউএল-এর একটি গুরুত্বপূর্ণ অংশ, যা কুয়েরি বা মিউটেশনের জন্য ডেটা ফেরত আনতে ব্যবহৃত হয়। প্রতিটি কুয়েরি বা মিউটেশনের জন্য আলাদা রেজোলভার থাকতে পারে, যা ডেটা ফেচিংয়ের জন্য ডেটাবেস বা অন্য সোর্স থেকে ডেটা আনতে সহায়ক। গ্রাফকিউএল-এ data fetching বা ডেটা ফেচিং বিভিন্ন সোর্স থেকে করা যেতে পারে যেমন REST API, ডেটাবেস, অথবা কাস্টম সোর্স। রেজোলভার এবং ডেটা ফেচিংয়ের মাধ্যমে, আপনি ক্লায়েন্টের নির্দিষ্ট কুয়েরি অনুযায়ী ডেটা সরবরাহ করতে পারেন।
গ্রাফকিউএল (GraphQL)-এ Resolvers হল একটি গুরুত্বপূর্ণ উপাদান, যা ক্লায়েন্টের কুয়েরি বা মিউটেশন পরিচালনার জন্য সার্ভারকে সাহায্য করে। Resolvers-এর মাধ্যমে, GraphQL সার্ভার ডেটার জন্য কাস্টম লজিক প্রয়োগ করতে সক্ষম হয় এবং প্রাপ্ত কুয়েরির ভিত্তিতে সঠিক ফলাফল প্রদান করে।
Resolvers কী?
Resolvers হল ফাংশন বা মেথড যা একটি নির্দিষ্ট কুয়েরি, মিউটেশন, বা সাবস্ক্রিপশনের জন্য ডেটা রিটার্ন বা পরিবর্তন করার দায়িত্ব পালন করে। এটি ক্লায়েন্টের কুয়েরি বা মিউটেশন অনুযায়ী ডেটা সংগ্রহ করে এবং সেই ডেটা গ্রাফকিউএল স্কিমা অনুযায়ী ফেরত পাঠায়।
প্রতিটি Resolver একটি নির্দিষ্ট Field এর জন্য কাজ করে। যখন গ্রাফকিউএল সার্ভার একটি কুয়েরি বা মিউটেশন পায়, তখন এটি নির্দিষ্ট ফিল্ডের জন্য একটি রেজোলভার কল করে, যাতে সেই ফিল্ডের জন্য সঠিক ডেটা আনা যায়।
Resolver কিভাবে কাজ করে?
GraphQL সার্ভারে প্রতিটি ফিল্ডের জন্য একটি resolver function ডিফাইন করা হয়। এটি কুয়েরি বা মিউটেশনের মধ্যে উল্লেখিত প্রতিটি ফিল্ডের জন্য চালিত হয়। Resolvers সাধারণত নিচের কিছু কার্য সম্পাদন করে:
- ডেটা সংগ্রহ করা: রেজোলভারটি ডেটাবেস বা API থেকে প্রয়োজনীয় ডেটা নিয়ে আসে।
- ডেটা প্রক্রিয়া করা: ডেটার মধ্যে কোনো পরিবর্তন বা ফিল্টারিং করা হতে পারে।
- ফলাফল ফেরত দেওয়া: রেজোলভার সঠিক ডেটা ফেরত দেয় যা কুয়েরি বা মিউটেশনের ফিল্ডে ফিরিয়ে আনা হবে।
এটি একটি Field থেকে ডেটা পাওয়ার জন্য একটি ফাংশন হিসেবে কাজ করে।
Resolver Structure
একটি সাধারণ রেজোলভারের স্ট্রাকচার এইরকম হতে পারে:
const resolvers = {
Query: {
getUser: (parent, args, context, info) => {
// এখানে getUser ফিল্ডের জন্য লজিক থাকবে
const { id } = args; // id আর্গুমেন্ট নেয়
return getUserById(id); // ডেটা ফেরত পাঠায়
}
},
Mutation: {
createUser: (parent, args, context, info) => {
const { name, email } = args;
return createUserInDatabase(name, email); // ডেটাবেসে নতুন ইউজার তৈরি করে
}
}
};
এখানে:
- parent: পূর্ববর্তী resolver থেকে প্রাপ্ত ডেটা
- args: কুয়েরি বা মিউটেশনের আর্গুমেন্টগুলি (যেমন
id,name,email) - context: সার্ভার সাইডে ব্যবহার করা হয় (এটি সাধারণত ইউজার অথেনটিকেশন, ডেটাবেস সংযোগ ইত্যাদির জন্য ব্যবহৃত হয়)
- info: কুয়েরির সম্পর্কে তথ্য (যেমন কোন ফিল্ডগুলো চাওয়া হয়েছে)
Resolver এর উপাদান
Resolvers সাধারণত Query, Mutation, বা Subscription এর অধীনে কাজ করে এবং ফিল্ড ভিত্তিক ডেটা ফেরত দেয়।
Query Resolvers:
কেবল ডেটা পড়তে ব্যবহৃত হয়। এটি একটি নির্দিষ্ট ফিল্ডের জন্য ডেটা রিটার্ন করে। উদাহরণস্বরূপ:const resolvers = { Query: { getUser: (parent, args) => { return { id: args.id, name: "John Doe" }; } } };Mutation Resolvers:
ডেটা তৈরি, আপডেট, বা মুছতে ব্যবহৃত হয়। উদাহরণস্বরূপ:const resolvers = { Mutation: { createUser: (parent, args) => { const newUser = { id: "1", name: args.name }; return newUser; } } };- Subscription Resolvers:
রিয়েল-টাইম ডেটা আপডেটের জন্য ব্যবহৃত হয়, যেমন চ্যাট সিস্টেম বা লাইভ ডেটা ফিড।
Resolver এর সাথে ব্যবহারযোগ্য অন্যান্য ফিচার
- Argument Handling:
রেজোলভারটি কুয়েরি বা মিউটেশনের আর্গুমেন্টগুলি গ্রহণ করে, যা তার কাজ করতে প্রয়োজনীয় তথ্য প্রদান করে। এই আর্গুমেন্টগুলি রেজোলভার ফাংশনের args প্যারামিটার হিসেবে পাওয়া যায়। - Context:
রেজোলভারটি context প্যারামিটারও পেতে পারে, যা সার্ভার সাইডের প্রেক্ষাপট সম্পর্কিত তথ্য ধারণ করে। এটি সাধারণত ইউজার অথেনটিকেশন, লগিং বা অন্যান্য সাধারণ কার্যকরী তথ্য প্রদান করতে ব্যবহৃত হয়। - Parent:
যদি এটি একটি Nested Query হয়, তাহলে parent প্যারামিটার ব্যবহার করা হয়। এটি আগের স্তরের রেজোলভার থেকে প্রাপ্ত ফলাফল ধারণ করে।
Resolver এর ব্যবহার উদাহরণ
ধরা যাক, আমাদের একটি User এবং Post টাইপ রয়েছে এবং আমরা একটি ইউজারের পোস্টগুলি প্রাপ্ত করতে চাই।
type User {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
content: String!
}
type Query {
getUser(id: ID!): User
}
এখন, রেজোলভারটি এরকম হবে:
const resolvers = {
Query: {
getUser: (parent, args) => {
const { id } = args;
const user = { id: "1", name: "John Doe" }; // ডেটা পাওয়া যাচ্ছে
return user; // ইউজার রিটার্ন করা হচ্ছে
}
},
User: {
posts: (parent) => {
// আগের resolver থেকে প্রাপ্ত `parent` ইউজারের `id` ব্যবহার করে পোস্টগুলি খুঁজে বের করা
if (parent.id === "1") {
return [
{ id: "101", title: "My first post", content: "This is a post." },
{ id: "102", title: "Another post", content: "This is another post." }
];
}
return [];
}
}
};
এখানে:
- getUser রেজোলভার ইউজার রিটার্ন করে।
- posts রেজোলভার User টাইপের একটি Nested ফিল্ড হিসাবে কাজ করে, এবং এটি
parent(এখানে ইউজার) এরidব্যবহার করে পোস্টের তালিকা রিটার্ন করে।
সারাংশ
Resolvers হল ফাংশন বা মেথড যা গ্রাফকিউএল কুয়েরি বা মিউটেশনগুলির জন্য ডেটা সংগ্রহ বা পরিবর্তন করার কাজ করে। তারা ক্লায়েন্টের কুয়েরি অনুযায়ী ডেটা ফেরত দেয় এবং সার্ভারের ডেটাবেস বা অন্যান্য উৎস থেকে ডেটা প্রাপ্তির জন্য লজিক প্রয়োগ করে। Resolvers এর মাধ্যমে GraphQL সার্ভার তার API এর কার্যকারিতা সম্পাদন করে এবং ডেটার সঠিক কাঠামো এবং ফলাফল প্রদান করে।
গ্রাফকিউএল (GraphQL)-এ Resolvers হল সেই ফাংশনগুলি যা কুয়েরি (Query) এবং মিউটেশন (Mutation) অপারেশনগুলির জন্য ডেটা রিটার্ন বা ডেটা পরিবর্তন করার কাজ করে। Resolvers মূলত ক্লায়েন্টের দ্বারা পাঠানো কুয়েরি বা মিউটেশনের সাথে সম্পর্কিত ডেটা প্রক্রিয়া করে এবং ফলাফল প্রদান করে।
Resolvers কী?
Resolvers হল ফাংশন যা কুয়েরি (Query) বা মিউটেশন (Mutation) এ পাঠানো অনুরোধগুলির জন্য বাস্তব ডেটা প্রক্রিয়া করে এবং ক্লায়েন্টের কাছে সঠিক ডেটা পাঠায়। যখন আপনি একটি কুয়েরি বা মিউটেশন চালান, সার্ভার তা ডিফাইন করা Resolver ফাংশনের মাধ্যমে কার্যকরী করে এবং ফলাফল ক্লায়েন্টে ফেরত পাঠায়।
যেকোনো গ্রাফকিউএল সার্ভারে, স্কিমা অনুযায়ী Resolvers ডিফাইন করা হয়, এবং প্রতিটি স্কিমা টাইপের জন্য একটি Resolver ফাংশন থাকতে হবে।
Query Resolvers তৈরি
Query Resolvers ডেটা পড়ার জন্য ব্যবহৃত হয়। সাধারণত, Query Resolvers ডেটাবেস থেকে ডেটা আনতে বা অন্য কোনো ডেটা সোর্স থেকে তথ্য নিতে ব্যবহৃত হয়।
ধরুন, আমাদের একটি User টাইপ আছে এবং আমরা ইউজারের তথ্য কুয়েরি করতে চাই। এখানে একটি Query Resolver এর উদাহরণ দেখানো হল।
Example: Query Resolver
type Query {
users: [User]
user(id: ID!): User
}
এখন, স্কিমা অনুযায়ী users এবং user কুয়েরি ফিল্ড রয়েছে। এগুলির জন্য আমরা Resolver তৈরি করব:
const resolvers = {
Query: {
// users কুয়েরির জন্য Resolver
users: () => {
return usersData; // usersData হল ডেটাবেস বা স্ট্যাটিক ডেটা
},
// user কুয়েরির জন্য Resolver
user: (parent, args) => {
const { id } = args;
return usersData.find(user => user.id === id); // ইউজারের আইডি দিয়ে খোঁজা
}
}
};
এখানে:
users: একটি Resolver ফাংশন যা সমস্ত ইউজারদের ফেরত আনে।user: একটি Resolver ফাংশন যা ইউজারের আইডি ব্যবহার করে নির্দিষ্ট ইউজারের তথ্য ফেরত আনে।
Mutation Resolvers তৈরি
Mutation Resolvers হল সেই ফাংশন যা ডেটা পরিবর্তন বা তৈরি করতে ব্যবহৃত হয়। সাধারণত, এই Resolvers নতুন ডেটা তৈরি করা, পুরানো ডেটা আপডেট করা বা ডেটা মুছে ফেলার জন্য ব্যবহৃত হয়।
ধরুন, আমাদের একটি createUser মিউটেশন ফিল্ড আছে, যা একটি নতুন ইউজার তৈরি করবে। এর জন্য আমরা একটি Mutation Resolver তৈরি করব।
Example: Mutation Resolver
type Mutation {
createUser(name: String!, email: String!): User
updateUser(id: ID!, name: String!): User
}
এখন, স্কিমা অনুযায়ী createUser এবং updateUser মিউটেশন ফিল্ড রয়েছে। এর জন্য Resolver গুলি হতে পারে:
const resolvers = {
Mutation: {
// createUser মিউটেশনের জন্য Resolver
createUser: (parent, args) => {
const { name, email } = args;
const newUser = { id: Date.now().toString(), name, email }; // নতুন ইউজার তৈরি
usersData.push(newUser); // নতুন ইউজার ডেটা যুক্ত করা
return newUser;
},
// updateUser মিউটেশনের জন্য Resolver
updateUser: (parent, args) => {
const { id, name } = args;
const user = usersData.find(u => u.id === id); // ইউজারের আইডি দিয়ে খোঁজা
if (user) {
user.name = name; // ইউজারের নাম আপডেট করা
return user;
}
return null; // ইউজার না পেলে null ফেরত
}
}
};
এখানে:
createUser: একটি Resolver ফাংশন যা নতুন ইউজার তৈরি করে এবংusersDataঅ্যারেতে যোগ করে।updateUser: একটি Resolver ফাংশন যা একটি ইউজারের নাম আপডেট করে এবং সংশোধিত ইউজার রিটার্ন করে।
Resolver ফাংশনে parent, args, এবং context ব্যবহার
Resolvers ফাংশনে তিনটি গুরুত্বপূর্ণ প্যারামিটার ব্যবহার করা হয়:
- parent: এটি পূর্ববর্তী Resolver এর ফলাফল (যদি থাকে)।
- args: এটি কুয়েরি বা মিউটেশন থেকে প্রাপ্ত আর্গুমেন্টস।
- context: এটি সাধারণত গ্লোবাল স্টেট বা ডেটাবেস কানেকশন যেমন সাধারণ তথ্য ধারণ করে, যা সমস্ত Resolver গুলিতে শেয়ার করা হয়।
Example: Using parent, args, and context
const resolvers = {
Query: {
user: (parent, args, context) => {
// context থেকে ডেটাবেস এক্সেস করা
return context.db.users.find(user => user.id === args.id);
}
},
Mutation: {
createUser: (parent, args, context) => {
const newUser = { id: Date.now().toString(), name: args.name, email: args.email };
context.db.users.push(newUser); // context-এ থাকা ডেটাবেসে নতুন ইউজার যোগ করা
return newUser;
}
}
};
এখানে, context একটি ডেটাবেস কানেকশন বা সাধারণ তথ্য ধারণ করে যা সব রিজলভারে শেয়ার করা হয়।
সারাংশ
Resolvers হল গ্রাফকিউএল-এর সবচেয়ে গুরুত্বপূর্ণ উপাদান, যেগুলি কুয়েরি (Query) এবং মিউটেশন (Mutation) ফিল্ডগুলির জন্য ডেটা প্রক্রিয়া করে এবং ক্লায়েন্টে ফলাফল ফেরত পাঠায়। Query Resolvers ডেটা পড়তে ব্যবহৃত হয়, এবং Mutation Resolvers ডেটা তৈরি, আপডেট বা মুছে ফেলার জন্য ব্যবহৃত হয়। Resolvers ক্লায়েন্টের কুয়েরি বা মিউটেশন অনুযায়ী ডেটা প্রসেস করে এবং ফলাফল প্রদান করে, এবং parent, args, এবং context প্যারামিটারগুলি ব্যবহার করে আরও নির্দিষ্ট কাজ করতে সাহায্য করে।
গ্রাফকিউএল (GraphQL)-এ Nested Resolvers এবং Parent-Child Relationship দুটি অত্যন্ত গুরুত্বপূর্ণ ধারণা, যা ডেটার মধ্যে সম্পর্ক তৈরি এবং সেই সম্পর্কের ভিত্তিতে ডেটা উদ্ধার করার প্রক্রিয়াকে সহজ করে তোলে। এগুলির মাধ্যমে আপনি একটি Parent Object থেকে সম্পর্কিত Child Object গুলি বের করে আনতে পারেন, এমনকি সেগুলি বিভিন্ন স্তরের মধ্যে গঠন করা থাকলেও।
Nested Resolvers কী?
Nested Resolvers হল একাধিক resolver এর মধ্যে সম্পর্ক স্থাপন, যেখানে এক resolver (parent) অন্য resolver (child) এর মাধ্যমে ডেটা ফেরত আনতে সহায়তা করে। এটি একটি parent-child relationship তৈরি করে, যেখানে একটি অবজেক্টের ডেটার ভিত্তিতে সম্পর্কিত অন্যান্য অবজেক্টের ডেটা ফেরত আসে।
ধরা যাক, আপনার কাছে একটি User টাইপ রয়েছে, যার মধ্যে posts রয়েছে, এবং প্রতিটি Post এর মধ্যে comments রয়েছে। এই সম্পর্ককে Nested Resolvers এর মাধ্যমে তৈরি করা হয়।
Nested Resolvers এর উদাহরণ
স্কিমা উদাহরণ
ধরা যাক, আমাদের একটি User টাইপ, Post টাইপ এবং Comment টাইপ রয়েছে।
type User {
id: ID!
name: String!
posts: [Post]
}
type Post {
id: ID!
title: String!
content: String!
comments: [Comment]
}
type Comment {
id: ID!
text: String!
}
এখানে:
Userটাইপেpostsফিল্ড রয়েছে, যাPostটাইপের একটি লিস্ট।Postটাইপেcommentsফিল্ড রয়েছে, যাCommentটাইপের একটি লিস্ট।
Resolvers উদাহরণ
এখন, আমরা একটি resolver তৈরি করব যা nested ভাবে ডেটা ফেরত আনবে। উদাহরণস্বরূপ, প্রথমে আমরা User এর তথ্য পেতে চাই, তারপর সেই User এর posts এবং প্রতিটি Post এর comments পেতে চাই।
const resolvers = {
Query: {
user: (parent, args, context, info) => {
// ইউজার ডেটা ফেরত
return {
id: "1",
name: "John Doe"
};
}
},
User: {
posts: (parent, args, context, info) => {
// User এর posts ফিরিয়ে দেয়া হচ্ছে, এখানে parent হল User
return [
{ id: "1", title: "My first post", content: "This is content of first post" },
{ id: "2", title: "Another post", content: "Content of another post" }
];
}
},
Post: {
comments: (parent, args, context, info) => {
// Post এর comments ফিরিয়ে দেয়া হচ্ছে, এখানে parent হল Post
return [
{ id: "1", text: "Great post!" },
{ id: "2", text: "Very informative." }
];
}
}
};
এখানে:
Query.user: ইউজারের তথ্য প্রদান করছে।User.posts:Userঅবজেক্টের মধ্যে থাকাpostsগুলি ফেরত আনছে।Post.comments: প্রতিটিPostএর মধ্যে থাকাcommentsফেরত আনছে।
কুয়েরি উদাহরণ
এখন, ক্লায়েন্টের পক্ষ থেকে একটি কুয়েরি দেখতে হবে, যাতে User এর posts এবং সেই Post এর comments দেখতে পাওয়া যায়:
query {
user(id: "1") {
name
posts {
title
comments {
text
}
}
}
}
ফলাফল:
{
"data": {
"user": {
"name": "John Doe",
"posts": [
{
"title": "My first post",
"comments": [
{ "text": "Great post!" },
{ "text": "Very informative." }
]
},
{
"title": "Another post",
"comments": [
{ "text": "Nice read!" }
]
}
]
}
}
}
এখানে:
- প্রথমে
Userএরnameপেয়েছি। - তারপর
Userএরpostsপেয়েছি, এবং প্রতিটিPostএরcommentsপেয়েছি।
Parent-Child Relationship
Parent-Child Relationship হল গ্রাফকিউএলে এমন একটি সম্পর্ক, যেখানে একটি টাইপ (Parent) অন্য একটি টাইপ (Child) এর সাথে সম্পর্কিত থাকে। Nested Resolvers এর মাধ্যমে এই সম্পর্ক বাস্তবায়িত করা হয়।
যেমন, উপরের উদাহরণে User হল Parent টাইপ, এবং Post ও Comment গুলি Child টাইপ। এখানে, User এর posts ফিল্ডের মাধ্যমে Post টাইপের অবজেক্ট পাওয়া যায়, এবং Post এর comments ফিল্ডের মাধ্যমে Comment টাইপের অবজেক্ট পাওয়া যায়।
Parent-Child Relationship-এর মাধ্যমে Resolver কাজের পদ্ধতি
- Parent Object থেকে ডেটা নেওয়া হয়।
- সেই ডেটার ভিত্তিতে Child Object গুলি বের করা হয়।
- Child Object গুলি আবার ডেটার মধ্যে লিঙ্কিং করা হয় এবং সেই অনুযায়ী সমস্ত সম্পর্কিত ডেটা ফেরত আসে।
এই প্রক্রিয়াটি nested resolvers হিসেবে পরিচিত।
Resolvers এর মধ্যে Parent-Child Relationship এর গুরুত্ব
- এফিসিয়েন্ট ডেটা রিট্রিভাল: Nested Resolvers ডেটার মধ্যে সম্পর্ক সহজে সংজ্ঞায়িত করে এবং ডেটা একসাথে ফিরিয়ে আনে, যার ফলে API এর কর্মক্ষমতা বাড়ে।
- নমনীয়তা: আপনি সহজেই ডেটার মধ্যে বিভিন্ন স্তরের সম্পর্ক তৈরি করতে পারেন। উদাহরণস্বরূপ,
UserএরpostsএবংPostএরcommentsএর মধ্যে সম্পর্ক স্থাপন করে সহজে প্রয়োজনীয় ডেটা নিয়ে আসা যায়। - স্বতন্ত্র রেজোলভার: প্রতিটি রেজোলভারকে একটি নির্দিষ্ট ফিল্ডের ডেটা অ্যাক্সেস করতে নিয়ন্ত্রণ দেয়া হয়, যা ডেটা প্রক্রিয়াকরণকে পরিষ্কার এবং সহজ করে তোলে।
সারাংশ
Nested Resolvers এবং Parent-Child Relationship গ্রাফকিউএল-এ ডেটার মধ্যে সম্পর্ক স্থাপন এবং সম্পর্কিত ডেটা একত্রে প্রাপ্তির গুরুত্বপূর্ণ উপাদান। Nested Resolvers ডেটার বিভিন্ন স্তরের মধ্যে সম্পর্ক তৈরি করতে এবং সেই সম্পর্কের মাধ্যমে ডেটা ফেরত আনতে সহায়তা করে, আর Parent-Child Relationship এর মাধ্যমে আপনি Parent টাইপ থেকে Child টাইপের ডেটা সহজে অ্যাক্সেস করতে পারেন। এই সম্পর্কের মাধ্যমে ডেটার সঠিক কাঠামো এবং তা থেকে প্রয়োজনীয় ডেটা নিয়ে আসা সম্ভব হয়।
গ্রাফকিউএল (GraphQL)-এ Resolver একটি গুরুত্বপূর্ণ উপাদান, যা কুয়েরি বা মিউটেশন প্রক্রিয়াকরণের সময় ডেটা ফিরিয়ে আনে। যখন কুয়েরি বা মিউটেশন করার জন্য ডেটা গ্রহণের প্রয়োজন হয়, তখন Resolver সেই ডেটা ফেরত দেওয়ার কাজ করে। তবে, অনেক সময় ডেটা সংগ্রহের প্রক্রিয়া Asynchronous হতে পারে, যেমন ডেটাবেস থেকে ডেটা পড়া বা API কল করা। এ ক্ষেত্রে Asynchronous Data Fetching ব্যবহার করা হয়, যাতে সার্ভার পেরোল বা ব্লক না হয়ে ডেটা সঠিকভাবে ফেচ করা যায়।
Resolver কী?
গ্রাফকিউএল-এর Resolver হল একটি ফাংশন যা ক্লায়েন্টের কুয়েরি বা মিউটেশন সম্পাদন করার সময় নির্দিষ্ট ফিল্ডের জন্য ডেটা প্রদান করে। প্রতিটি ফিল্ডের জন্য একটি Resolver থাকে যা ওই ফিল্ডের ডেটা ফেচ করে। যখন Query বা Mutation এর মাধ্যমে কোনো ডেটার অনুরোধ করা হয়, তখন Resolver সেই ডেটা পাওয়ার জন্য কার্যকরী হয়।
Asynchronous Data Fetching
অনেক সময়, ডেটা Fetching এর প্রক্রিয়া Asynchronous হতে পারে। উদাহরণস্বরূপ:
- ডেটাবেসের সঙ্গে যোগাযোগ করা
- একটি এক্সটার্নাল API-তে কল করা
- লম্বা সময় নেওয়া কোনো প্রসেসিং কাজ
এ ধরনের অপারেশনগুলো Asynchronous হতে পারে, যার মানে হল যে ফাংশনটির কাজ শেষ না হওয়া পর্যন্ত অন্য কোনো কাজ থামবে না। গ্রাফকিউএল Resolvers-এ Asynchronous প্রক্রিয়া চালানোর জন্য Promises বা Async/Await ব্যবহার করা হয়।
Asynchronous Resolver এর উদাহরণ
ধরা যাক, আমাদের একটি User টাইপ আছে, এবং আমরা users নামে একটি কুয়েরি তৈরি করতে চাই, যা ডেটাবেস থেকে ইউজারদের তথ্য ফিরিয়ে আনবে।
আমরা এখানে Async/Await ব্যবহার করে Asynchronous data fetching দেখাব।
Schema Example:
type Query {
users: [User]
}
type User {
id: ID!
name: String!
email: String!
}
Resolver Example:
এখানে, আমরা একটি users কুয়েরি Resolver তৈরি করব, যা ডেটাবেস থেকে ইউজারদের তথ্য Asynchronously ফেচ করবে।
const resolvers = {
Query: {
// Asynchronous resolver for 'users' query
users: async () => {
try {
const users = await fetchUsersFromDatabase(); // Asynchronous DB call
return users;
} catch (error) {
throw new Error('Error fetching users');
}
},
},
};
async function fetchUsersFromDatabase() {
// Imagine this is a DB call that fetches users from a database
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ id: '1', name: 'John Doe', email: 'john@example.com' },
{ id: '2', name: 'Jane Doe', email: 'jane@example.com' },
]);
}, 1000); // Simulate a delay in DB fetching
});
}
এখানে:
- users কুয়েরি জন্য async ফাংশন ব্যবহার করা হয়েছে।
fetchUsersFromDatabase()একটি Asynchronous ফাংশন যা একটি Promise ফেরত দেয়। এই Promise হল ডেটাবেস থেকে ডেটা ফেচ করার প্রক্রিয়া।awaitব্যবহার করা হয়েছে যাতে ডেটা ফেচ করার প্রক্রিয়া সম্পন্ন না হওয়া পর্যন্ত পরবর্তী কোড 실행 না হয়।
Promise ব্যবহার করা
তবে, async/await ব্যবহার না করে Promise পদ্ধতিতেও Asynchronous data fetching করা যায়। নিচে Promise ব্যবহার করে কিভাবে কাজ করা যায় তা দেখানো হলো।
const resolvers = {
Query: {
users: () => {
return new Promise((resolve, reject) => {
fetchUsersFromDatabase()
.then(users => resolve(users))
.catch(err => reject(new Error('Error fetching users')));
});
},
},
};
এখানে:
usersকুয়েরি Resolver একটিPromiseফেরত দেয়।fetchUsersFromDatabase()ফাংশনটি then ও catch ব্লক ব্যবহার করে ডেটা প্রাপ্তি এবং ত্রুটি পরিচালনা করে।
Asynchronous Resolver এর ব্যবহার
Asynchronous Resolver সাধারণত তখন ব্যবহার করা হয় যখন:
- ডেটাবেস থেকে ডেটা ফেচ করা:
ডেটাবেসের সাথে যোগাযোগ করার জন্য সঠিকভাবে Asynchronous কল করা প্রয়োজন। যেমন, একটি SQL বা NoSQL ডেটাবেস থেকে ডেটা পড়া। - API কল:
বাইরের API-তে HTTP রিকুয়েস্ট পাঠিয়ে ডেটা ফিরিয়ে আনা। যেমন, থার্ড-পার্টি সিস্টেম থেকে তথ্য গ্রহণ। - File I/O:
সার্ভারের মধ্যে ফাইলের তথ্য পড়া বা লেখা যেখানে ব্লকিং অপারেশন হতে পারে। - Long-running Operations:
এমন কাজ যা সময় নিয়ে কাজ করতে পারে, যেমন কমপ্লেক্স প্রসেসিং বা মেইল পাঠানো।
Resolver-এ Asynchronous Data Fetching এর সুবিধা
- ক্লায়েন্টের অভিজ্ঞতা উন্নত:
একাধিক Asynchronous কাজ একসঙ্গে সম্পাদিত হওয়ার ফলে অ্যাপ্লিকেশন দ্রুত এবং দক্ষভাবে কাজ করতে পারে, যা ক্লায়েন্টের অভিজ্ঞতাকে উন্নত করে। - প্রতিক্রিয়া সময় কমানো:
যখন একাধিক Asynchronous কাজ একযোগে চলছে, তা সার্ভারকে একযোগে কাজ করার সুযোগ দেয়, যার ফলে প্রতিক্রিয়া সময় কমে। - Non-blocking:
Asynchronous ফাংশনগুলি সার্ভারকে ব্লক না করে অন্য কাজগুলো চলতে দেয়, ফলে সার্ভারের কর্মক্ষমতা বৃদ্ধি পায়।
সারাংশ
Asynchronous Data Fetching গ্রাফকিউএল-এ Resolver এর মধ্যে ব্যবহৃত একটি গুরুত্বপূর্ণ কৌশল, যা বিভিন্ন ধরনের দীর্ঘ সময় নেয়া অপারেশন, যেমন ডেটাবেস কল বা API রিকুয়েস্ট, নির্বিঘ্নে পরিচালনা করে। Async/Await বা Promise ব্যবহারের মাধ্যমে, গ্রাফকিউএল রিসলভারগুলো ডেটা ফেচ করার জন্য Asynchronous প্রক্রিয়া অনুসরণ করে, এবং এভাবে সার্ভারের কর্মক্ষমতা বৃদ্ধি পায় এবং ক্লায়েন্টের অভিজ্ঞতা উন্নত হয়।
Read more