GraphQL: query, resolver ও প্রয়োজনমতো ডেটা
GraphQL: Queries, Resolvers, and Data Selection
এই পাঠের সূচিপত্র
এই পাঠে যা শিখবেন
- Schema, query, mutation ও resolver
- Over-fetching বনাম query complexity
- Laravel client থেকে GraphQL response বিচার
সমস্যা দিয়ে শুরু
Mobile app product-এর নাম ও দাম চায়, desktop reviews-ও চায়। REST endpoint সব client-কে একই বড় response দিলে অপ্রয়োজনীয় data যায়; অনেক ছোট endpoint দিলে round trip বাড়ে। GraphQL client-কে schema-এর মধ্যে selected fields চাইতে দেয়। তবে flexible query database-এর কাজ সীমাহীন করার অনুমতি নয়।
সহজ করে বুঝি
GraphQL typed schema data ও operation-এর contract প্রকাশ করে। Query data পড়ে, mutation state-changing operation বোঝায়; resolver field-এর value তৈরি করে। Nested field resolve করতে naïve per-row query চালালে N+1 হয়। Selection set অনুযায়ী output ছোট হলেও server computation বড় হতে পারে। Depth, complexity, pagination ও authorization limits দরকার। HTTP 200-এর সঙ্গে errors array আসতে পারে এবং partial data থাকতে পারে; শুধু transport status check যথেষ্ট নয়।
পরিচিত একটি উপমা
রেস্তোরাঁর menu থেকে customer দরকারি পদ বেছে নেন। কিন্তু “প্রতিটি পদের সব supplier-এর সব order” চাইলে রান্নাঘরে বিশাল কাজ তৈরি হবে। Menu schema choices দেয়; cost limit ও permission এখনও restaurant-এর দায়িত্ব।
নকশাটি দেখুন
Diagram লোড হচ্ছে…
Diagram-এর text flow দেখুন
flowchart TD C[GraphQL operation] --> S[Schema validation] S --> A[Authorization and query cost limit] A --> R[Resolvers and batched loaders] R --> D[(Database or services)] D --> O[Selected data plus possible errors]
প্রথমে syntax/schema validation, তারপর operation cost ও actor permission। Resolver data fetch করে; batched loader related IDs এক query-তে আনতে পারে। Field-level authorization parent object access থেকে আলাদা হতে পারে। Response-এ partial result থাকলে কোন field ব্যর্থ তা client-এর policy অনুযায়ী handle করতে হবে।
PHP ও Laravel-এ প্রয়োগ
এই service fragment Laravel HTTP Client দিয়ে configured trusted GraphQL service ডাকে। services.catalog.graphql_url ও token secret config-এ থাকবে। Project-এ GraphQL server package ধরে নেওয়া হয়নি; এটি client example। Variables query string interpolation-এর বদলে typed argument পাঠায়।
use Illuminate\Support\Facades\Http;
$response = Http::acceptJson()
->withToken(config('services.catalog.token'))
->timeout(5)
->post(config('services.catalog.graphql_url'), [
'query' => 'query Product($id: ID!) { product(id: $id) { id name } }',
'variables' => ['id' => (string) $productId],
]);
$response->throw();
$body = $response->json();
if (!is_array($body) || !empty($body['errors'])) {
throw new \RuntimeException('Catalog GraphQL operation failed.');
}
$product = data_get($body, 'data.product');সুবিধা, সীমাবদ্ধতা ও trade-off
GraphQL client-specific representations সহজ করতে পারে এবং strongly documented schema দেয়। কিন্তু resolver cost, caching ও authorization design জটিল। REST GET response CDN-এ সহজ cache করা যায়; GraphQL POST operation cache করতে normalized operation/variables ও identity scope দরকার। Persisted operations flexibility সীমিত করে predictability বাড়াতে পারে। Small API-তে REST যথেষ্ট হলে GraphQL বাধ্যতামূলক নয়।
সাধারণ ভুল
- HTTP 200 দেখেই সব field সফল বলা।
- Resolver-এ প্রতিটি child row-এর জন্য আলাদা Eloquent query।
- Schema field থাকলেই সব user-এর access আছে ধরে নেওয়া।
আরও একটু গভীরে
Schema evolution-এ field deprecate করে client migration সময় দিন। Field remove বা nullable থেকে non-null করা compatibility affect করতে পারে। Resolver timeout ও upstream failure partial data হিসেবে প্রকাশ হবে কি না explicit contract। Introspection বন্ধ করলেই security সম্পূর্ণ নয়; authorization ও abuse protection অপরিহার্য। Query batching এক request-এ বহু operation লুকিয়ে rate limit bypass করতে পারে; cost-aware accounting বিবেচনা করুন।
মনে রাখুন
GraphQL selection flexibility দেয়, unlimited computation নয়। Response errors, query cost ও field authorization প্রথম design-এই ধরুন। Laravel client-ও transport এবং operation success আলাদা পরীক্ষা করবে।
নিজে চেষ্টা করুন
Product list-এর nested category ও reviews query আঁকুন। Resolver naïve হলে কত query হতে পারে হিসাব করুন, তারপর batched loading plan লিখুন। Partial data গ্রহণযোগ্য screen ও all-or-nothing screen-এর error policy আলাদা করুন।
নিজের বোঝা যাচাই করুন
1. GraphQL database?
না। এটি API query language ও execution model। Resolver SQL, cache বা অন্য service থেকে data আনতে পারে।
2. Small response মানে cheap query?
না। কয়েকটি aggregate field-ও বড় computation করতে পারে। Output bytes আর server work আলাদা।
3. Variables কেন?
Operation structure স্থিতিশীল রেখে input আলাদা পাঠায়। String interpolation এড়ায়; তবু authorization ও validation লাগবে।
4. errors থাকলে কী করব?
Partial result গ্রহণযোগ্য কি না feature অনুযায়ী ঠিক করুন। Example conservative ভাবে operation fail করে; সব client-এর জন্য একই policy বাধ্যতামূলক নয়।
5. N+1 কীভাবে কমাব?
Bounded eager loading বা request-scoped batched loader ব্যবহার করা যায়। Batch-এ user/tenant authorization scope বজায় রাখতে হবে।
আরও পড়ুন
এই পাঠের কুইজ
এই পাঠ থেকে ২টি প্রশ্ন। উত্তর দিয়ে ব্যাখ্যা দেখুন; অধ্যায়ের কুইজ আলাদাভাবে দিতে হবে।
এই পাঠের ২টি প্রশ্নের উত্তর দিন। পাস করতে দুটিই সঠিক হতে হবে।
জমা দেওয়ার পর সঠিক উত্তর ও ব্যাখ্যা দেখবেন। ফলাফল এই ব্রাউজারে সংরক্ষিত থাকবে। অনুশীলনের ফল অধ্যায় সম্পন্নের হিসাবে যোগ হয় না।
অগ্রগতি এই ব্রাউজারে সংরক্ষিত থাকে। শুধু পাঠ খুললে সম্পন্ন হয় না।