paint-brush
যখন আরেস্টকে বিশ্রাম দেওয়ার সময় হয়দ্বারা@johnjvester
2,368 পড়া
2,368 পড়া

যখন আরেস্টকে বিশ্রাম দেওয়ার সময় হয়

দ্বারা John Vester13m2024/05/13
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

এই নিবন্ধটি ডেটা পুনরুদ্ধারের জন্য GraphQL এবং REST API-এর তুলনা করে, জটিল পরিস্থিতিতে গ্রাফকিউএল-এর নমনীয়তা এবং দক্ষতা কীভাবে উৎকৃষ্ট হয় তা প্রদর্শন করে। এটি Heroku এর সাথে অ্যাপোলো সার্ভার স্থাপনের বিশদ বিবরণ দেয় এবং গ্রাফকিউএল-এ প্রমাণীকরণ এবং রিয়েল-টাইম ডেটাতে আসন্ন সামগ্রী টিজ করে।
featured image - যখন আরেস্টকে বিশ্রাম দেওয়ার সময় হয়
John Vester HackerNoon profile picture
0-item
1-item


আমার কয়েক বছরের বিল্ডিং পরিষেবার মাধ্যমে, 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 ব্যবহার করবেন

অনেকগুলি সাধারণ ব্যবহারের ক্ষেত্রে রয়েছে যখন গ্রাফকিউএল REST এর চেয়ে ভাল পদ্ধতি:


  • আপনি কীভাবে ডেটা পুনরুদ্ধার করবেন সে সম্পর্কে আপনার যখন নমনীয়তার প্রয়োজন হয়: আপনি বিভিন্ন সংস্থান থেকে জটিল ডেটা আনতে পারেন তবে সবগুলি একক অনুরোধে ৷ (আমি এই নিবন্ধে এই পথে ডুব দেব।)
  • যখন ফ্রন্টএন্ড টিমকে ঘন ঘন UI বিকশিত করতে হবে: দ্রুত ডেটা প্রয়োজনীয়তা পরিবর্তনের জন্য ব্যাকএন্ডকে শেষ পয়েন্টগুলি সামঞ্জস্য করতে এবং ব্লকার সৃষ্টি করতে হবে না।
  • যখন আপনি ওভার-ফেচিং এবং আন্ডার-ফেচিং কমাতে চান: কখনও কখনও REST-এর জন্য আপনাকে আপনার প্রয়োজনীয় সমস্ত ডেটা সংগ্রহ করার জন্য একাধিক এন্ডপয়েন্টে আঘাত করতে হয় (আন্ডার-ফেচিং), অথবা একটি একক এন্ডপয়েন্টে আঘাত করলে আপনার আসলে প্রয়োজনের চেয়ে অনেক বেশি ডেটা ফেরত আসে (অতিরিক্ত- আনা)।
  • আপনি যখন জটিল সিস্টেম এবং মাইক্রোসার্ভিস নিয়ে কাজ করছেন: কখনও কখনও একাধিক উত্সকে তাদের ডেটার জন্য একটি একক API স্তর আঘাত করতে হবে৷ GraphQL একটি একক API কলের মাধ্যমে সেই নমনীয়তা প্রদান করতে পারে।
  • আপনার যখন রিয়েল-টাইম ডেটার প্রয়োজন হয় তখন আপনার কাছে ঠেলে দেওয়া হয়: GraphQL বৈশিষ্ট্যগুলি সাবস্ক্রিপশন , যা রিয়েল-টাইম আপডেট প্রদান করে। চ্যাট অ্যাপ বা লাইভ ডেটা ফিডের ক্ষেত্রে এটি কার্যকর। (আমি একটি ফলো-আপ নিবন্ধে আরও বিস্তারিতভাবে এই সুবিধাটি কভার করব।)

অ্যাপোলো সার্ভার কি?

যেহেতু GraphQL এর সাথে আমার দক্ষতা পোলিশ করা হয়নি, আমি এই নিবন্ধটির জন্য Apollo Server এর সাথে যাওয়ার সিদ্ধান্ত নিয়েছি।


Apollo Server হল একটি GraphQL সার্ভার যা যেকোনো GraphQL স্কিমার সাথে কাজ করে। লক্ষ্য হল একটি GraphQL API তৈরির প্রক্রিয়া সহজ করা। অন্তর্নিহিত নকশাটি এক্সপ্রেস বা কোয়ার মতো ফ্রেমওয়ার্কের সাথে ভালভাবে সংহত করে। আমি আমার পরবর্তী নিবন্ধে রিয়েল-টাইম ডেটার জন্য সাবস্ক্রিপশন ( গ্রাফকিউএল-ডব্লিউএস লাইব্রেরির মাধ্যমে) লাভ করার ক্ষমতা অন্বেষণ করব।


যেখানে অ্যাপোলো সার্ভার সত্যিই উজ্জ্বল হয় তা হল অ্যাপোলো এক্সপ্লোরার, একটি অন্তর্নির্মিত ওয়েব ইন্টারফেস যা বিকাশকারীরা তাদের গ্রাফকিউএল এপিআইগুলি অন্বেষণ এবং পরীক্ষা করতে ব্যবহার করতে পারে৷ স্টুডিওটি আমার জন্য একটি নিখুঁত ফিট হবে, কারণ এটি প্রশ্নের সহজ নির্মাণ এবং গ্রাফিকাল বিন্যাসে API স্কিমা দেখার ক্ষমতা দেয়।

আমার গ্রাহক 360 ব্যবহার কেস

এই উদাহরণের জন্য, ধরা যাক গ্রাহকের একটি 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 ইনস্টল করতে হয়।

গ্রহণযোগ্যতার মানদণ্ড পূরণ: আমার গ্রাহক 360 উদাহরণ

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 সার্ভার আরও তৈরি করব।


একটি সত্যিই মহান দিন আছে!