আগের পর্ব :
GraphQL কি এবং কেন? GraphQL পার্ট - ১
GraphQL শুরু করার জন্য যা যা জানা দরকার:
- Schema Definition
- Resolver
১. Schema Definition (স্কিমা ডেফিনিশন)
GraphQL-এর স্কিমা হলো একটি ব্লুপ্রিন্ট যা ডেটার স্ট্রাকচার এবং সেই ডেটার সাথে কীভাবে ইন্টারঅ্যাক্ট করা যাবে তা নির্ধারণ করে। স্কিমা ডেফিনিশনে বিভিন্ন ধরনের ডেটা টাইপ এবং অপারেশন (query, mutation) ডিফাইন করা হয়।
Scalar Types
একটি মৌলিক ডাটা টাইপ যা একটি একক মানের প্রতিনিধিত্ব করে এবং সাধারণত প্রিমিটিভ ধরনের ডেটা ধারণ করে। GraphQL এ ডিফল্টভাবে ৫টি scalar টাইপ দেয়া থাকে:
- Int: পূর্ণসংখ্যা।
- Float: দশমিক সংখ্যা।
- String: টেক্সট।
- Boolean: সত্য বা মিথ্যা।
- ID: ইউনিক আইডেন্টিফায়ার যা সাধারণত ইউনিক হতে হবে।
এছাড়াও আমরা চাইলে প্রয়োজন মতো custom scalar তৈরি করে নিতে পারি।
Object Types
মূলত ডেটার স্ট্রাকচার তৈরিতে ব্যবহৃত হয়। একটি Object টাইপের একাধিক ফিল্ড থাকে, যেগুলো scalar দিয়ে ডিফাইন করা হয়।
উদাহরণ:
type User {
id: ID!
role: String!
name: String!
email: String!
phone: String
age: Int
}
এখানে User
হলো Object Type যা ইউজারের ইনফরমেশন ধরে রাখে। এই User টাইপে ছয়টি ফিল্ড রয়েছে: id
, role
, name
, email
, phone
এবং age
। আমরা scalar দিয়ে প্রত্যেক ফিল্ডের মান নির্ধারণ করেছি।
ID!
মানে হচ্ছে এই ফিল্ডের মান অবশ্যই থাকতে হবে, যাrequired
বা non-nullable নির্দেশ করে।phone
এবংage
ঐচ্ছিক, মানে না থাকলেও চলবে।
Query Type
GraphQL স্কিমার এন্ট্রি পয়েন্ট যেখানে ডেটা ফেচ করার জন্য ক্লায়েন্ট কী রিকোয়েস্ট করতে পারবে তা ডিফাইন করা হয়। মূলত Query টাইপের মাধ্যমে GraphQL সার্ভারকে ক্লায়েন্ট জানায় যে কী কী ডেটা রিটার্ন করবে।
type Query {
user(id: ID!): User
users: [User!]!
}
users: [User!]!
: এটি ব্যবহারকারীদের একটি তালিকা রিটার্ন করবে এবং সেই তালিকায়null
মান থাকতে পারবে না।User!
মানে প্রতিটি আইটেম non-nullable, এবং[User!]!
মানে তালিকাটিওrequired
।user(id: ID!): User
: নির্দিষ্টid
দিয়ে একটি User অবজেক্ট রিটার্ন করবে। এখানেid
একটি বাধ্যতামূলক আর্গুমেন্ট।
একটি সাধারণ GraphQL Query হতে পারে এরকম:
query {
users {
id
name
email
}
}
উপরের Query এর মাধ্যমে আমরা সব ব্যবহারকারীর id
, name
, এবং email
পেতে চাইছি।
Mutation Type
Object Type যা ডেটা পরিবর্তন বা রাইট করার জন্য ব্যবহৃত হয়। যেখানে ডেটা পরিবর্তন (create, update, delete) করার জন্য প্রয়োজনীয় অপারেশনগুলো ডিফাইন করা হয়।
type Mutation {
createUser(role: String!, name: String!, email: String!, phone: String, age: Int): User
updateUser(id: ID!, role: String!, name: String, email: String, phone: String, age: Int): User
deleteUser(id: ID!): Boolean
}
createUser
: একটিrole
,name
,email
,phone
, এবংage
আর্গুমেন্ট রিসিভ করে নতুন User তৈরি করবে এবং সেটি রিটার্ন করবে। এখানেrole
,name
,email
বাধ্যতামূলক, কিন্তুphone
এবংage
ঐচ্ছিক।updateUser
:id
আর্গুমেন্ট বাধ্যতামূলক এবং বাকিগুলো ঐচ্ছিক।deleteUser
:id
আর্গুমেন্ট বাধ্যতামূলক এবং এটি একটি Boolean মান রিটার্ন করবে।
Input Types
অনেক আর্গুমেন্ট একসাথে লেখার পরিবর্তে ইনপুট টাইপ ব্যবহার করা যায়, যা কোডকে সংক্ষিপ্ত ও ক্লিন রাখে।
input CreateUserInput {
role: String!
name: String!
email: String!
phone: String
age: Int
}
type Mutation {
createUser(input: CreateUserInput): User
}
এখানে CreateUserInput
ইনপুট টাইপ ব্যবহার করে আমরা createUser
মিউটেশনে প্রয়োজনীয় আর্গুমেন্টগুলো পাস করছি।
Enumeration/Enum Types
যেখানে একটি ফিল্ডের মান নির্দিষ্ট মানের মধ্যে সীমাবদ্ধ হতে হবে সেখানে Enum টাইপ ব্যবহার করা হয়।
enum UserRole {
admin
user
}
type User {
id: ID!
role: UserRole!
name: String!
email: String!
phone: String
age: Int
}
এখানে UserRole
এনাম ব্যবহার করে role
ফিল্ডের মানকে admin
অথবা user
এর মধ্যে সীমাবদ্ধ করা হয়েছে।
Directive
কোন ফিল্ড বা কোয়েরি/মিউটেশন বা ফ্রেগমেন্টের উপর কন্ডিশন এপলাই করতে ডিরেক্টিভ ব্যবহার করা হয়। GraphQL এ ডিফল্টভাবে @include
এবং @skip
ডিরেক্টিভ দেয়া থাকে।
type User {
id: ID!
role: UserRole!
name: String!
email: String!
phone: String
age: Int @include(if: false) # অথবা age @skip(if: true)
}
এখানে age
ফিল্ডটি বাদ পড়বে কারণ @include(if: false)
নির্দেশ করা হয়েছে।
একটি custom ডিরেক্টিভ তৈরি করে আমরা ডেভেলপারদের ওয়ার্ন করতে পারি যদি একটি ফিল্ড deprecated হয়ে যায়:
directive @deprecated(reason: String) on FIELD_DEFINITION | ENUM_VALUE
type User {
id: ID!
role: UserRole!
name: String!
email: String!
phone: String
age: Int @deprecated(reason: "age will be deprecated soon, use dob instead of it")
dob: String
}
এখন age
ফিল্ড ব্যবহার করার সময় ডেভেলপারদের একটি ওয়ার্নিং দেখানো হবে, যেমন: "age will be deprecated soon, use dob instead of it"
।
২. Resolvers (রিজলভার)
Resolvers হলো ফাংশন যা GraphQL স্কিমার জন্য ডেটা ফেচ বা প্রসেস করার জন্য ব্যবহৃত হয়। রিজলভার ফাংশন ছাড়া GraphQL এর স্কিমা কেবলমাত্র ডেটার স্ট্রাকচার জানাবে, কিন্তু ডেটা ফেচ করার পদ্ধতি থাকবে না। রিজলভার ফাংশনই ঠিক করে দেয় যে কীভাবে ক্লায়েন্টের অনুরোধের ভিত্তিতে ডেটা রিটার্ন করা হবে।
প্রত্যেকটি রিজলভার ফাংশন সাধারণত তিন/চারটি প্যারামিটার গ্রহণ করে:
parent
(root): অবজেক্টকে নির্দেশ করে, যা বর্তমানে রিজলভ হচ্ছে।args
: কোয়েরির আর্গুমেন্ট, যা ক্লায়েন্ট পাঠিয়েছে।context
: এমন একটি অবজেক্ট যা সকল রিজলভারের জন্য শেয়ার করা হয় এবং অথেন্টিকেশন, ডাটাবেস কানেকশন, ইত্যাদি ধরার জন্য ব্যবহার করা হয়।info
: এটি অবজেক্ট যা কোয়েরি সম্পর্কিত ইনফো এবং এক্সিকিউশন প্রসেস সম্পর্কিত মেটাডেটা ধারণ করে (অপশনাল)।
আমরা যেহেতু লারভেল ইউজ করবো তাই রিজলভারের এক্সাম্পল দেখালাম না , আপাতত মনে রাখুন রিজলভার কি, তাহলেই হবে।
ধন্যবাদ সবাইকে।
আবার দেখা হবে পরের পর্বে।
লারাভেল গ্রাফকিউলের জন্য নিচের ভিডিও ফলো করতে পারেন।
Bitfumes চ্যানেলের এই প্লেলিস্ট ফলো করতে পারেন।
Andre Madarang এই ভিডিও টা দেখতে পারেন।