আমার কয়েক বছরের বিল্ডিং পরিষেবার মাধ্যমে, RESTful API হল আমার প্রাথমিক যাতায়াত। যাইহোক, যদিও REST এর যোগ্যতা রয়েছে, তার মানে এই নয় যে এটি প্রতিটি ব্যবহারের ক্ষেত্রে সর্বোত্তম পদ্ধতি। বছরের পর বছর ধরে, আমি শিখেছি যে, মাঝে মাঝে, নির্দিষ্ট পরিস্থিতিতে আরও ভাল বিকল্প হতে পারে। REST-এর সাথে লেগে থাকা শুধুমাত্র এই কারণে যে আমি এটি সম্পর্কে উত্সাহী—যখন এটি সঠিকভাবে উপযুক্ত নয়—শুধুমাত্র প্রযুক্তিগত ঋণ এবং পণ্যের মালিকের সাথে একটি টানাপোড়েন সম্পর্ক তৈরি করে৷
RESTful পদ্ধতির সাথে সবচেয়ে বড় ব্যথার পয়েন্টগুলির মধ্যে একটি হল একটি ব্যবসায়িক সিদ্ধান্তের জন্য প্রয়োজনীয় সমস্ত তথ্য পুনরুদ্ধার করার জন্য একাধিক অনুরোধ করা।
একটি উদাহরণ হিসাবে, ধরা যাক আমি একজন গ্রাহকের 360-ভিউ চাই। আমাকে নিম্নলিখিত অনুরোধগুলি করতে হবে:
GET /customers/{some_token}
গ্রাহকের মূল তথ্য প্রদান করেGET /addresses/{some_token}
একটি প্রয়োজনীয় ঠিকানা সরবরাহ করেGET /contacts/{some_token}
যোগাযোগের তথ্য প্রদান করেGET /credit/{some_token}
মূল আর্থিক তথ্য প্রদান করে
যদিও আমি বুঝি REST-এর অন্তর্নিহিত লক্ষ্য হল প্রতিটি রিসোর্সের জন্য প্রতিক্রিয়াগুলিকে লেজার-কেন্দ্রিক রাখা, এই দৃশ্যটি ভোক্তাদের পক্ষে আরও কাজ করে। শুধুমাত্র একটি ব্যবহারকারী ইন্টারফেস তৈরি করতে যা একটি সংস্থাকে গ্রাহকের সাথে ভবিষ্যতের ব্যবসার সাথে সম্পর্কিত সিদ্ধান্ত নিতে সাহায্য করে, গ্রাহককে একাধিক কল করতে হবে
এই নিবন্ধে, আমি দেখাব কেন GraphQL একটি RESTful API-এর চেয়ে পছন্দের পদ্ধতি, যেখানে দেখানো হবে কিভাবে অ্যাপোলো সার্ভার (এবং অ্যাপোলো এক্সপ্লোরার) স্থাপন করতে হয় এবং গ্রাফকিউএল-এর সাথে দ্রুত কাজ করতে হয়।
আমি Node.js এর সাথে আমার সমাধান তৈরি করার এবং Heroku এ আমার সমাধান স্থাপন করার পরিকল্পনা করছি।
অনেকগুলি সাধারণ ব্যবহারের ক্ষেত্রে রয়েছে যখন গ্রাফকিউএল REST এর চেয়ে ভাল পদ্ধতি:
যেহেতু GraphQL এর সাথে আমার দক্ষতা পোলিশ করা হয়নি, আমি এই নিবন্ধটির জন্য Apollo Server এর সাথে যাওয়ার সিদ্ধান্ত নিয়েছি।
Apollo Server হল একটি GraphQL সার্ভার যা যেকোনো GraphQL স্কিমার সাথে কাজ করে। লক্ষ্য হল একটি GraphQL API তৈরির প্রক্রিয়া সহজ করা। অন্তর্নিহিত নকশাটি এক্সপ্রেস বা কোয়ার মতো ফ্রেমওয়ার্কের সাথে ভালভাবে সংহত করে। আমি আমার পরবর্তী নিবন্ধে রিয়েল-টাইম ডেটার জন্য সাবস্ক্রিপশন ( গ্রাফকিউএল-ডব্লিউএস লাইব্রেরির মাধ্যমে) লাভ করার ক্ষমতা অন্বেষণ করব।
যেখানে অ্যাপোলো সার্ভার সত্যিই উজ্জ্বল হয় তা হল অ্যাপোলো এক্সপ্লোরার, একটি অন্তর্নির্মিত ওয়েব ইন্টারফেস যা বিকাশকারীরা তাদের গ্রাফকিউএল এপিআইগুলি অন্বেষণ এবং পরীক্ষা করতে ব্যবহার করতে পারে৷ স্টুডিওটি আমার জন্য একটি নিখুঁত ফিট হবে, কারণ এটি প্রশ্নের সহজ নির্মাণ এবং গ্রাফিকাল বিন্যাসে API স্কিমা দেখার ক্ষমতা দেয়।
এই উদাহরণের জন্য, ধরা যাক গ্রাহকের একটি 360-ভিউ প্রদান করার জন্য আমাদের নিম্নলিখিত স্কিমার প্রয়োজন:
type Customer { token: String name: String sic_code: String } type Address { token: String customer_token: String address_line1: String address_line2: String city: String state: String postal_code: String } type Contact { token: String customer_token: String first_name: String last_name: String email: String phone: String } type Credit { token: String customer_token: String credit_limit: Float balance: Float credit_score: Int }
আমি নিম্নলিখিত GraphQL প্রশ্নগুলিতে ফোকাস করার পরিকল্পনা করছি:
type Query { addresses: [Address] address(customer_token: String): Address contacts: [Contact] contact(customer_token: String): Contact customers: [Customer] customer(token: String): Customer credits: [Credit] credit(customer_token: String): Credit }
গ্রাহকরা যে গ্রাহককে দেখতে চান তার জন্য টোকেন প্রদান করবে। আমরা উপযুক্ত ঠিকানা, যোগাযোগ এবং ক্রেডিট অবজেক্টগুলিও পুনরুদ্ধার করার আশা করি। লক্ষ্য হল একটি একক API কলের পরিবর্তে এই সমস্ত তথ্যের জন্য চারটি ভিন্ন API কল করা এড়ানো।
আমি আমার স্থানীয় ওয়ার্কস্টেশনে graphql-server-customer
নামে একটি নতুন ফোল্ডার তৈরি করে শুরু করেছি। তারপর, অ্যাপোলো সার্ভার ডকুমেন্টেশনের শুরু করুন বিভাগটি ব্যবহার করে, আমি একটি টাইপস্ক্রিপ্ট পদ্ধতি ব্যবহার করে এক এবং দুই ধাপ অনুসরণ করেছি।
এর পরে, আমি আমার স্কিমা সংজ্ঞায়িত করেছি এবং পরীক্ষার জন্য কিছু স্ট্যাটিক ডেটাও অন্তর্ভুক্ত করেছি। সাধারণত, আমরা একটি ডাটাবেসের সাথে সংযোগ করব, তবে স্ট্যাটিক ডেটা এই ডেমোর জন্য ভাল কাজ করবে।
নীচে আমার আপডেট করা index.ts
ফাইল আছে:
import { ApolloServer } from '@apollo/server'; import { startStandaloneServer } from '@apollo/server/standalone'; const typeDefs = `#graphql type Customer { token: String name: String sic_code: String } type Address { token: String customer_token: String address_line1: String address_line2: String city: String state: String postal_code: String } type Contact { token: String customer_token: String first_name: String last_name: String email: String phone: String } type Credit { token: String customer_token: String credit_limit: Float balance: Float credit_score: Int } type Query { addresses: [Address] address(customer_token: String): Address contacts: [Contact] contact(customer_token: String): Contact customers: [Customer] customer(token: String): Customer credits: [Credit] credit(customer_token: String): Credit } `; const resolvers = { Query: { addresses: () => addresses, address: (parent, args, context) => { const customer_token = args.customer_token; return addresses.find(address => address.customer_token === customer_token); }, contacts: () => contacts, contact: (parent, args, context) => { const customer_token = args.customer_token; return contacts.find(contact => contact.customer_token === customer_token); }, customers: () => customers, customer: (parent, args, context) => { const token = args.token; return customers.find(customer => customer.token === token); }, credits: () => credits, credit: (parent, args, context) => { const customer_token = args.customer_token; return credits.find(credit => credit.customer_token === customer_token); } }, }; const server = new ApolloServer({ typeDefs, resolvers, }); const { url } = await startStandaloneServer(server, { listen: { port: 4000 }, }); console.log(`Apollo Server ready at: ${url}`); const customers = [ { token: 'customer-token-1', name: 'Acme Inc.', sic_code: '1234' }, { token: 'customer-token-2', name: 'Widget Co.', sic_code: '5678' } ]; const addresses = [ { token: 'address-token-1', customer_token: 'customer-token-1', address_line1: '123 Main St.', address_line2: '', city: 'Anytown', state: 'CA', postal_code: '12345' }, { token: 'address-token-22', customer_token: 'customer-token-2', address_line1: '456 Elm St.', address_line2: '', city: 'Othertown', state: 'NY', postal_code: '67890' } ]; const contacts = [ { token: 'contact-token-1', customer_token: 'customer-token-1', first_name: 'John', last_name: 'Doe', email: '[email protected]', phone: '123-456-7890' } ]; const credits = [ { token: 'credit-token-1', customer_token: 'customer-token-1', credit_limit: 10000.00, balance: 2500.00, credit_score: 750 } ];
প্রত্যাশিত হিসাবে সবকিছু কনফিগার করার সাথে, আমরা সার্ভার শুরু করতে নিম্নলিখিত কমান্ডটি চালাই:
$ npm start
অ্যাপোলো সার্ভার 4000 পোর্টে চলার সাথে, আমি অ্যাপোলো এক্সপ্লোরার অ্যাক্সেস করতে http://localhost:4000/ URL ব্যবহার করেছি। তারপর আমি নিম্নলিখিত উদাহরণ ক্যোয়ারী সেট আপ:
query ExampleQuery { addresses { token } contacts { token } customers { token } }
অ্যাপোলো এক্সপ্লোরারে এটি দেখতে কেমন:
উদাহরণ ক্যোয়ারী বোতাম টিপুন, আমি যাচাই করেছি যে প্রতিক্রিয়া পেলোডটি আমি index.ts
এ দেওয়া স্ট্যাটিক ডেটার সাথে সারিবদ্ধ।
{ "data": { "addresses": [ { "token": "address-token-1" }, { "token": "address-token-22" } ], "contacts": [ { "token": "contact-token-1" } ], "customers": [ { "token": "customer-token-1" }, { "token": "customer-token-2" } ] } }
আমার গ্রাহক 360 ব্যবহারের ক্ষেত্রে আরও কিছু করার আগে, আমি ক্লাউডে এই পরিষেবাটি চালাতে চেয়েছিলাম।
যেহেতু এই নিবন্ধটি নতুন কিছু করার বিষয়ে, আমি দেখতে চেয়েছিলাম যে হেরোকুতে আমার অ্যাপোলো সার্ভার স্থাপন করা কতটা কঠিন হবে।
আমি জানতাম যে আমাকে স্থানীয়ভাবে চালানো এবং ক্লাউডে কোথাও চালানোর মধ্যে পোর্ট নম্বরের পার্থক্যগুলি সমাধান করতে হবে। আমি নীচে দেখানো হিসাবে সার্ভার শুরু করার জন্য আমার কোড আপডেট করেছি:
const { url } = await startStandaloneServer(server, { listen: { port: Number.parseInt(process.env.PORT) || 4000 }, });
এই আপডেটের সাথে, আমরা পোর্ট 4000 ব্যবহার করব যদি না একটি পরিবেশ পরিবর্তনশীলে একটি PORT মান নির্দিষ্ট করা থাকে।
Gitlab ব্যবহার করে, আমি এই ফাইলগুলির জন্য একটি নতুন প্রকল্প তৈরি করেছি এবং Heroku কমান্ড-লাইন ইন্টারফেস (CLI) ব্যবহার করে আমার Heroku অ্যাকাউন্টে লগ ইন করেছি:
$ heroku login
আপনি Heroku-এ তাদের CLI বা Heroku ড্যাশবোর্ড ওয়েব UI দিয়ে একটি নতুন অ্যাপ তৈরি করতে পারেন। এই নিবন্ধের জন্য, আমরা CLI ব্যবহার করব:
$ heroku create jvc-graphql-server-customer
CLI কমান্ড নিম্নলিখিত প্রতিক্রিয়া ফিরিয়ে দিয়েছে:
Creating ⬢ jvc-graphql-server-customer... done https://jvc-graphql-server-customer-b62b17a2c949.herokuapp.com/ | https://git.heroku.com/jvc-graphql-server-customer.git
কমান্ডটি স্বয়ংক্রিয়ভাবে রিমোট হিসাবে Heroku দ্বারা ব্যবহৃত সংগ্রহস্থল যুক্ত করেছে:
$ git remote heroku origin
ডিফল্টরূপে, Apollo Server উৎপাদন পরিবেশে Apollo Explorer নিষ্ক্রিয় করে। আমার ডেমোর জন্য, আমি এটিকে Heroku এ চলমান রেখে দিতে চাই। এটি করার জন্য, আমাকে বিকাশে NODE_ENV
পরিবেশ পরিবর্তনশীল সেট করতে হবে। আমি নিম্নলিখিত CLI কমান্ড দিয়ে এটি সেট করতে পারি:
$ heroku config:set NODE_ENV=development
CLI কমান্ড নিম্নলিখিত প্রতিক্রিয়া ফিরিয়ে দিয়েছে:
Setting NODE_ENV and restarting ⬢ jvc-graphql-server-customer... done, v3 NODE_ENV: development
এখন আমরা হেরোকুতে আমাদের কোড স্থাপন করার অবস্থানে আছি:
$ git commit --allow-empty -m 'Deploy to Heroku' $ git push heroku
Heroku ড্যাশবোর্ডের একটি দ্রুত দৃশ্য দেখায় যে আমার অ্যাপোলো সার্ভার কোনো সমস্যা ছাড়াই চলছে:
আপনি যদি Heroku-এ নতুন হন, তাহলে এই নির্দেশিকা আপনাকে দেখাবে কিভাবে একটি নতুন অ্যাকাউন্ট তৈরি করতে হয় এবং Heroku CLI ইনস্টল করতে হয়।
GraphQL এর সাথে, আমি নিম্নলিখিত প্রশ্নের সাথে আমার গ্রাহক 360 ব্যবহারের ক্ষেত্রে গ্রহণযোগ্যতার মানদণ্ড পূরণ করতে পারি:
query CustomerData($token: String) { customer(token: $token) { name sic_code token }, address(customer_token: $token) { token customer_token address_line1 address_line2 city state postal_code }, contact(customer_token: $token) { token, customer_token, first_name, last_name, email, phone }, credit(customer_token: $token) { token, customer_token, credit_limit, balance, credit_score } }
আমাকে যা করতে হবে তা হল customer-token-1
এর মান সহ একটি একক গ্রাহক token
ভেরিয়েবলে পাস করতে হবে:
{ "token": "customer-token-1" }
আমরা একটি একক GraphQL API কল ব্যবহার করে সমস্ত ডেটা পুনরুদ্ধার করতে পারি:
{ "data": { "customer": { "name": "Acme Inc.", "sic_code": "1234", "token": "customer-token-1" }, "address": { "token": "address-token-1", "customer_token": "customer-token-1", "address_line1": "123 Main St.", "address_line2": "", "city": "Anytown", "state": "CA", "postal_code": "12345" }, "contact": { "token": "contact-token-1", "customer_token": "customer-token-1", "first_name": "John", "last_name": "Doe", "email": "[email protected]", "phone": "123-456-7890" }, "credit": { "token": "credit-token-1", "customer_token": "customer-token-1", "credit_limit": 10000, "balance": 2500, "credit_score": 750 } } }
নীচে আমার Heroku অ্যাপ থেকে চলমান Apollo Explorer থেকে একটি স্ক্রিনশট রয়েছে:
আমি আমার কর্মজীবনের আগের কথা মনে করি যখন জাভা এবং C# বিকাশকারী গ্রহণের জন্য একে অপরের বিরুদ্ধে প্রতিদ্বন্দ্বিতা করছিল। বিতর্কের প্রতিটি পক্ষের উকিলরা প্রমাণ করতে প্রস্তুত ছিল যে তাদের নির্বাচিত প্রযুক্তিই সেরা পছন্দ … এমনকি যখন এটি ছিল না।
এই উদাহরণে, আমরা একাধিক উপায়ে আমার গ্রাহক 360 ব্যবহারের ক্ষেত্রে দেখা করতে পারতাম। একটি প্রমাণিত RESTful API ব্যবহার করলে কাজ হত, তবে প্রয়োজনীয় সমস্ত ডেটা পুনরুদ্ধার করতে একাধিক API কলের প্রয়োজন হত। অ্যাপোলো সার্ভার এবং গ্রাফকিউএল ব্যবহার করে আমাকে একটি একক API কলের মাধ্যমে আমার লক্ষ্য পূরণ করতে দেয়।
আমি এটাও পছন্দ করি যে আমার টার্মিনালে মাত্র কয়েকটি কমান্ড দিয়ে হেরোকুতে আমার গ্রাফকিউএল সার্ভার স্থাপন করা কতটা সহজ। এটি আমাকে বাস্তবায়নে ফোকাস করতে দেয়—অবকাঠামোর বোঝা বন্ধ করে এবং আমার কোডকে বিশ্বস্ত তৃতীয়-পক্ষ প্রদানকারীর কাছে চালাতে। সবচেয়ে গুরুত্বপূর্ণ, এটি আমার ব্যক্তিগত মিশন বিবৃতির সাথে সঙ্গতিপূর্ণ:
“আপনার বৌদ্ধিক সম্পত্তির মূল্যকে প্রসারিত করে এমন বৈশিষ্ট্য/কার্যকারিতা প্রদানের উপর আপনার সময় ফোকাস করুন। অন্য সবকিছুর জন্য ফ্রেমওয়ার্ক, পণ্য এবং পরিষেবার সুবিধা নিন।"
- জে. ভেস্টার
আপনি যদি এই নিবন্ধটির উত্স কোডে আগ্রহী হন তবে এটি গিটল্যাবে উপলব্ধ।
কিন্তু অপেক্ষা করুন... আরো আছে!
আমার ফলো-আপ পোস্টে, সাবস্ক্রিপশনের সাথে প্রমাণীকরণ এবং রিয়েল-টাইম ডেটা পুনরুদ্ধার বাস্তবায়নের জন্য আমরা আমাদের GraphQL সার্ভার আরও তৈরি করব।
একটি সত্যিই মহান দিন আছে!