নোড — Node js ( তৃতীয় পর্ব )
--
complete node js developer course by Andrew mead
Content:
- 11. API Authentication & Security
- 12. Sorting Pagination & Filtering
- 13. File Uploads
- 14. Sending Email and Heroku deployment
প্রথম পর্ব
দ্বিতীয় পর্ব
11. API Authentication & Security
Logging out
tokens এর token array তে আমরা বিভিন্ন ধরনের token স্টোর করে রেখেছি , যেমন কেউ android থেকে লগইন করল আবার কেউ pc থেকে লগইন করলো আবার কেউ অন্য কোন ডিভাইস থেকে লগইন করলো সব গুলোই tokens array তে স্টোর করে রাখবে । এখন আমরা যে টোকেন টি ডিলিট করতে চাই সেটা নিচের কোড দিয়ে করতে পারবো ।
এখন প্রথমে আমরা auth ফাইলে next() এর আগে req.token = token
দিয়ে ফ্রন্ট এন্ড থেকে আশা টোকেন সেট করে দিবো ।
এখন user.tokens মানে user database এর সব গুলো টোকেন থেকে ফিলটার করবো আমাদের ফ্রন্ট এন্ড এর টোকেনের সাথে যেটা req.token এ আছে । যদি মিলে যায় তাহলে কন্ডিশন false আসবে । আর false আসলে সেটা আর req.user.tokens এ সেভ হবে না বরঞ্চ সেটা ফেলে দিবে এরপর সেটা সেভ করবো । এখন আর ঐ টোকেন দিয়ে লগইন করতে পারবে না ।
সেটা চেক করার জন্য আমরা নিচের এই লিঙ্ক গুলো থেকে চেক করতে পারবো যে request গুলো আমরা পোস্টম্যানে সেভ করে রেখেছিলাম ।
{{url}}/users/me -> read user{{url}}/users/logout -> logout{{url}}/users/login -> login
logout এর সাথে token bearer পাঠিয়ে টোকেন ডিলিট করে দিবো । এরপর ঐ টোকেন দিয়ে login করলে এরর দিবে বলবে যে authenticate user না । এরপর read user দিয়ে সেটা চেক করা যাবে যে আসলেই token ডিলিট হয়েছে কিনা অর্থাৎ ঐ টোকেন এখানে পাওয়া যাবে না ।
এখন আমরা চাচ্ছি যে ধরেন আমার একটি netflex একাউন্ট আছে সেটা দিয়ে আমার আরও ৫-৬ জন বন্ধু ব্যাবহার করে কিন্তু এখন আমি সবার টাই ডিলিট করতে চাচ্ছি সেজন্য নিচের কোড গুলো লিখতে হবে ।
এখানে req.user.tokens = []
এটা দিয়ে জাস্ট array র ভেলু ০ করে দিলাম । যতই টোকেন থাকুক এই লাইন এক্সিকিউট করলে খালি হয়ে যাবে ।
এখন পোস্টম্যান ওপেন করে নতুন একটি রিকোয়েস্ট তৈরি করবো এই লিঙ্কে ।
{{url}}/users/logoutAll
Hiding Private data
অনেক সময় দেখা যায় যে আমরা চাইনা যে কিছু ডাটা ইউজার দেখুক । যেমন লগইনের সময় আমরা চাইনা যে ইউজার তার পাসওয়ার্ড এবং টোকেন দেখুক সেজন্য আমরা user router এর send() মেথডে একটি কাস্টমাইজ মেথড কল করি যেটা ফিলটার করে ডাটা নিয়ে আসবে ।
res.send({ user: user.getPublicProfile() })
এরপর models এর user ফাইলে getPublicProfile() নামে একটি মেথড তৈরি করে সেখানে ডাটাগুলো ফিলটারের কাজ করবো ।
এরপর পোস্টম্যান ওপেন করে login url এ রিকোয়েস্ট করবো ।
এখানে user password এবং token আসবে না ।
কিন্তু যদি আমরা এভাবে দেই তাহলে সুধু একটি রাউটেই এই মেথড কল করতে পারবো কিন্তু আমরা যদি সকল মেথডের জন্যই যদি চাই যে এই মেথড ইমপ্লিমেন্ট করতে তাহলে এই getPublicProfile() মেথডের জায়গায় toJSON() লিখব তাহলেও একি ফলাফল আসবে কারণ এটি হচ্ছে Build in ফাংশন । কিন্তু তখন আবার send method এ এই ফাংশন কল না করে অন্য ভাবে লিখতে হবে ।
res.send( user )
এভাবে লিখলেই হবে ।
Authentication user endpoints
এখন আমরা ডিলিট সেকশনে আগে endpoint এ user id দিয়ে চেক করতাম যে authenticate কিনা কিন্তু এখন token ব্যাবহারের কারণে findById() মেথডের প্রয়োজন নাই কারণ auth বেবহার করেছি, ওইখানেই এটা চেক করে req.user সেট করে দিয়েছি আর তাই মেঝের কয়েকটা লাইন কমেন্ট আউট করে দিয়েছি । এরপর ওই user জাস্ট remove() কল করে ডাটাবেজে সেভ করে send() মেথডে req.user পাঠিয়ে দিয়েছি আর endpoint এ শেষে id এর পরিবর্তে me দিয়েছি ।
update operation
update operation এ আমরা url এ পরিবর্তন করেছি, patch() মেথডে auth ইনক্লুড করে দিয়েছি, findById() বাদ দিয়ে দিয়েছি, আর যতগুলো user আছে ততগুলোতে req.user দিয়ে দিয়েছি আর ইউজার না পেলে যে 404 এরর দিতো সেটা বাদ দিয়ে দিয়েছি কারণ এই এরর হেন্ডেল্টা auth এই করেছি ।
User-Task Relationship
relationship এ আমরা এখানে দেখবো যে একটি ইউজারের id পেলে ওই ইউজার কি কি Task তৈরি করেছে সেগুলো দেখা যাবে অর্থাৎ একটি ইউজার অনেকগুলো টাস্ক তৈরি করতে পারে ।
আবার একটি Task এর id পেলে ঐ task কোন user তৈরি করেছে ঐটা বের করতে পারবো ।
এখন প্রথমে task এর টা দেখবো অর্থাৎ task এর id দিলে user এর ইনফরমেশন বের করে আনবে । এরপরে user এর associate করবো ।
task এর association করার জন্য প্রথমে task model এ এক্সট্রা একটি attribute অ্যাড করবো ।
type এ আমরা একটি object id নিবো আর ref এ মডেলের নাম দিয়ে দিবো । এরপরে
এখানে auth দিয়ে ইউজার ভেরিফাই করে নিয়েছি অর্থাৎ authenticate ইউজার ছারা কেউ টাস্ক create করতে পারবে না এরপর front end থেকে আসা ডাটা দিয়ে Task object তৈরি করেছি এখানে … হচ্ছে spread operator অর্থাৎ body তে জাই থাকুক সব নিয়ে নিবে এরপর try-catch এ ডাটাবেজে ডাটা task ডাটা সেভ করেছি ।
এখন ডাটা দেখার জন্য এই কোডগুলো লিখেছি । এখানে যে id টা দিয়েছি এটা Task এর id . কারণ টাস্কের id দিয়েই ওর ডাটা আর user এর ডাটা নিয়ে আসবো । এরপর ঐ ডাটাগুলো populate করেছি ।
এখন user এর ইনফরমেশন দেখবো । যে কোন particular ইউজার কি কি task তৈরি করেছে ।
এজন্য প্রথমে আমরা user model এ একটি রিলেশনশিপ তৈরি করবো যেটা ডিরেক্ট ডাটাবেজে সেভ হবে না জাস্ট বলে দিবে যে কিভাবে রিলেশনশিপটা তৈরি হবে ।
এখানে এটার নাম দিছি tasks
এরপর ref দিয়ে বুঝিয়েছি যে কোন মডেলের সাথে রিলেশনশিপ তৈরি করবে । এখানে সেটা দিয়েছি Task
। foreignField এ owner
দিয়েছি জাতে বুঝিয়েছি যে owner প্রপার্টির সাথে রিলেশনশিপ তৈরি করবে আর localField এ _id দিয়েছি যে এই _id র সাথে মিল রেখে রিলেশনশিপ টা তৈরি করবে ।
এখানে পাশের চিত্র মতে ডাটাটা জাস্ট পপুলেট করেছি ।
Authenticating Task Endpoint
এখন আমরা একটি ইউজার দিয়ে লগইন করে ২ টি Task তৈরি করবো এরপর আরেকটি ইউজার দিয়ে লগইন করে আরও ২ টি Task তৈরি করবো ।
এক ইউজারের টাস্ক আরেক ইউজারে দেখাবে না আবার আরেক ইউজারের টাস্ক অন্য কোন ইউজারের কাছে এক্সেস দিবে না । অর্থাৎ কেউ কারো টা আপডেট, ডিলিট, গেট করতে পারবে না ।
এজন্য নিচের মতো করে task router এর কোড আপডেট করবো ।
এখানে update router এ একটা জিনিস লক্ষ করি —
const task = await Task.findOne({ _id: req.params.id, owner: req.user._id })
findOne() এ আমরা একটি জিনিস ক্রস চেক করে নিয়েছি সেটা হচ্ছে যে প্রথমে _id:req.params.id দিয়ে বোঝাচ্ছে যে আমাদের ডাটাবেজে এই particular task এর যে id আছে সেটা আর আমরা request করার সময় যে id টা দিয়েছি সেই দুইটা এক কিনা । এরপরের অবজেক্টের ক্ষেত্রে owner: req.user._id দিয়ে বোঝাচ্ছে যে আমাদের ডাটাবেজে যে owner id আছে সেটা আর আমরা যে ইউজারের থ্রু তে লগইন করেছি সেই ইউজারের id এক কিনা । এরকম ভাবে যতগুলো findOne() আছে সবগুলোতেই একি জিনিস চেক করেছি ।
Cascade delete task
কোন ইউজার নিজের একাউন্ট রিমুভ করে দিলে সেই ইউজার যতগুলো task তৈরি করেছে সবগুলো ডিলিট করে দিবো । অর্থাৎ associate ডাটাবেজের সব ভেলু ডিলিট করে দিবো ।
এজন্য remove middleware তৈরি করবো আর user router এ যেরকম আছে সেরকম ই রাখবো ।
12. Sorting, Pagination & Filtering
Timestamp
schema তৈরি করার পর শেষে আরেকটা অবজেক্টে timestamps: true দিলে ২ টা প্রপার্টি দিবে ডাটাবেজে । একটি হচ্ছে createdAt
আরেকটা হচ্ছে updatedAt
এদের ভেলুগুলতে time দেওয়া থাকে ।
Filtering data
match নামে একটি ফাকা অবজেক্ট ভেরিয়েবল নিয়েছি এরপর query তে completed এর ভেলু যেটা আসবে সেটা true or false আসবে কিন্তু সেটা স্ট্রিং হিশেবে আসবে তাই সেটা চেক করেছি if condition এর ভেতর । যদি ‘true’ আশে তাহলে boolean value true সেট হবে অন্যথায় false সেট হবে ।
Pagination
pagination এর জন্য option অবজেক্টের আন্ডারে limit এবং skip অবজেক্ট বেবহার করা হয় কারণ front end থেকে রিকোয়েস্ট করার সময় limit এবং skip query তে দিয়ে দিতে হয় কিন্তু সেই ভেলু গুলো string হিশেবে আসে তাই এটাকে integer এ parse করে নিতে হয় ।
limit হচ্ছে প্রতি পেজে কয়টা ইলিমেন্ট পাঠাবে । আর skip হচ্ছে কয়টা ইলিমেন্ট পর থেকে নিবে । যেমন নিচে limit দিয়েছি ২ আর skip দিয়েছি ৩ । আমাদের ডাটাবেজে true ভেলুর ডাটা আছে মোট ৪ টা । এখানে সে প্রথম ৩ টা স্কিপ করে এরপর ২ টা নিয়ে আসবে কিন্তু আমাদের বাকি থাকে আর ১ টা । তাই ১ টাই নিয়ে এসেছে ।
Sorting
আমরা sort অবজেক্টের ভেতর createdAt: -1 দিয়ে সরাসরি বলে দিতে পারি অথবা front end থেকে কি পাঠালো সেটার ভিত্তিতেও সেট করে দিতে পারি । এখানে -1 এর মানে হচ্ছে descending অর্ডারে সর্ট করবে আর 1 দেওয়ার অর্থ হচ্ছে Ascending অর্ডারে সর্ট করবে ।
const parts = req.query.sortBy.split(':') sort[parts[0]] = parts[1] === 'desc' ? -1 : 1
এই দুইটা লাইনের মানে হচ্ছে আমরা /tasks?sortBy=createdAt:desc টাইপের রিকোয়েস্ট দিবো । তখন এটাকে এক্সত্রাক্ট করে নিয়ে এনালাইসিস করবো । এখানে : এর পরিবর্তে _ ও দিতে পারি যেকোনো কিছু বেবহার করতে পারি । createdAt এর ভেলু desc দিলে এর ভেলু -1 set করে দিবো আর asc আসলে 1 set করে দিবো প্রগ্রামেটিকেলি ।
13. File Uploads
node js এ সরাসরি ফাইল( image/pdf/docx ) আপলোড করার অপশন নাই এর জন্য multer নামে একটি npm প্যাকেজ ইন্সটল করতে হবে । আমরা আগে
নরমালি রিকোয়েস্ট করার সময় json ডাটা পাঠাইতাম, node সেটাকে javascript object এ রূপান্তরিত করতো কিন্তু multer এখানে binary ডাটা নিয়ে সেটাকে প্রসেস করে ।
npm i multer
এখানে জাস্ট স্যাম্পল দেখানোর জন্য কোড টা লেখা হয়েছে যে কোডটুকু দিয়ে ফাইল আপলোড করা যায় ।
এখানে প্রথমে multer প্যাকেজটা লোড করে নিয়েছি । এরপর multer() মেথডের ভেতর dest: ‘image’ দিয়ে বুঝিয়েছি যে রুট ডিরেক্টরিতে image নামে একটি ডিরেক্টরি তৈরি হবে । পোস্টম্যানের মাধ্যমে বা ফ্রন্টেন্ড থেকে ফাইল আপলোড করলে সেগুলো এই image ডিরেক্টরিতে সেভ হবে ।
এরপর একটি POST রাউটার তৈরি করেছি যেটার দ্বিতীয় আর্গুমেন্টে upload.single(‘document’) দিয়েছি যেটার অর্থ হচ্ছে যখন postman/frontend থেকে ফাইল (image/docx/pdf) পাঠাব তখন সেটা document নামের ভেরিয়েবলে থাকবে ।
postman এ যেয়ে body তে ক্লিক করে নিচের ড্রপ ডাউনে form-data সিলেক্ট করে key তে document দেওয়ার পরে এর পাশে drop down এ text এর পরিবর্তে file সিলেক্ট করলে file upload করার অপশন আসবে সেখান থেকে ফাইল আপলোড করতে হবে । এরপর send এ ক্লিক করলে ফাইল আপলোড হয়ে যাবে । এরপর image directory তে যেয়ে আপলোডের সময় ফাইলের যে extension ছিল ( ex: jpg, jpeg, pdf ) সেটা দিতে হবে ফাইলের নাম edit করে ।
এখন user router এ একটি endpoint তৈরি করবো যেখানে আমাদের profile picture আপলোড করবো ।
Validation file upload
validation অনেক ধরনের হতে পারে যেমন ফাইল সাইজ, ফাইল টাইপ ইত্যাদি । অনেক সময় আমরা চাই যে ফাইল 1mb র বেশি হবে না আবার ফাইল টাইপ jpg/png/pdf/doc হতে হবে ।
এখানে limits এ ফাইল সাইজ 1000000 দেওয়া হয়েছে অর্থাৎ 1MB র বেশি সাইজের ফাইল আপলোড করতে পারবে না ।
এরপর fileFilter() নামের মেথডে file type ভ্যালিডেসন করা হয়েছে । প্রথমটা req, এরপরেরটা file শেষেরটা callback . এখানে ৩ ধরনের ঘটনা ঘটতে পারে । ফাইল টাইপ ঠিক নাই তখন error through করবে, ফাইল টাইপ ঠিক আছে এবং ফাইল আপলোড ও হয়েছে তখন callback এ undefined এবং true দিবে, আরেকটি হতে পারে যে ফাইল টাইপ ঠিক আছে কিন্তু ফাইল আপলোড হয় নাই তখন callback এ undefined এবং false দিবে ।
pdf ফাইল ফিলটার করার জন্য সুধু endWith() মেথড বেবহার করলেই হয়ে যাবে কিন্তু যদি একধিক ফাইল টাইপ ফিলটার করতে যাই তখন regular expression এ করতে হবে । regular expression বেবহার করার জন্য match() ফাংশন বেবহার করতে হয় । regular expression চেক করার জন্য নিচের এই লিঙ্ক বেবহার করা হয় সাধারণত ।
এখন আমরা এই validation টা আমাদের user router এ এপ্লাই করবো ।
Handling express errors
এখানে ফাইল আপলোডে এরর দিলে multer এর অনেক হাবি যাবি এরর দিবে কিন্তু এই এরর টা আমরা express এ হেন্ডেল করতে পারি constructive way তে ।
error, req, res, next এগুলো express অটোম্যাটিকভাবে হেন্ডেল করতে পারে ।
Adding image to user profile
এর আগে আমরা ইমেজ অ্যাড করেছিলাম image/avater নামের ফাইলে যেটা আমরা বলে দিয়েছিলাম multer method এর ভেতর dest:'avaters'
property তে, কিন্তু যখন আমরা প্রজেক্ট deploy করবো heroku/aws এ তখন আমাদের ফাইল সিস্টেম ডিলিট হয়ে যাবে আর তাই আমরা এখন ইমেজ ফাইলগুলো সরাসরি ডাটাবেজে আপলোড করবো binary ফাইল হিশেবে । আর তাই dest: ‘avater’ এই লাইনটি ডিলিট করে দিবো । এখন পোস্টম্যানের মাধ্যমে ইমেজ আপলোড করে ডাটাবেজে গেলে দেখা যাবে যে binary ফাইল সেভ হয়েছে এখন ঐ বাইনারি ফাইলের কোড টুকু কপি করবো just বাইনারি ডাটা টুকু ।
"avater" : { "$binary" : "<binary data>"
এরপর নিচের এই লিঙ্কে যাবো
এইখানে এই কোডটুকু লিখবো । তাহলে ইমেজ দেখা যাবে ।
এখন আমরা ডিলিট করার কোড লিখবো ।
এখন এই রিকোয়েস্ট টা করবো নিচের এই endpoint এ
{{url}}/users/me/avater
এই রিকোয়েস্ট টা করলে শুধু image এর বাইনারি ফাইল ডিলিট হয়ে যাবে কিন্তু ইউজার থেকে যাবে আবার নতুন করে upload এর রিকোয়েস্ট করলে ইমেজের বাইনারি ফাইল আপলোড হবে ।
Serving up files
এখন ব্রাউজারে একটি নতুন ট্যাব ওপেন করে নিচের এই লিঙ্ক দিয়ে ইন্টার দিলে ইমেজ পেয়ে যাবো ডাটাবেজ থেকে । image jpg থাকলে jpg দিবো বা অন্য কোন এক্সটেনশন থাকলে ঐটা দিবো ।
http://localhost:3000/users/5fbb6464eb9375166846cda9/avater
এই id টা আমরা ডাটাবেজ থেকে নিয়েছি । user id
Auto cropping and image formatting
যখন user profile রিকোয়েস্ট করা হতো তখন user password এবং token ডিলিট করে তারপর বাকি ডাটা আসতো security র জন্য । একি ভাবে আমরা ওইখানে avater ডিলিট করে দিবো কারণ ইমেজ লোড করতে অনেক ডাটা দরকার হবে না হলে ।
delete userObject.avater
image resizing, rotation, extraction, compositing, png/jpg/jpeg ফরমেটে কনভার্সন এসব করার জন্য sharp প্যাকেজ বেবহার করা হয় । এইটা ইন্সটল করার জন্য নিচের কমান্ডটি বেবহার করা হয় ।
npm i sharp
এই কোডটুকু লিখে /users/:id/avater এই রাউটে নিচের কোড টুকু লিখবো । আগে jpg ছিল এখানে শুধু png লিখে দিবো ।
res.set('Content-Type', 'image/png')
প্রথমে sharp() মেথডের মাধ্যমে front end থেকে পাঠানো ইমেজ নিয়ে resize করবো এরপর png তে কনভার্ট করবো শেষে সেটাকে buffer এ কনভার্ট করে এরপর ডাটাবেজে সেভ করবো ।
এখন নিচের এই লিঙ্কে গেলে দেখা যাবে যে ইমেজ ক্রপ হয়ে png তে সেভ হয়ে গেছে ।
http://localhost:3000/users/5fbb6464eb9375166846cda9/avater
14. Sending Email and Heroku deployment
After some times we have add email service.
Environment variables
একেক অপারেটিং সিস্টেমে environment variable সেটআপ করার পদ্ধতি আলাদা আলাদা। এই সমস্যা দূর করার জন্য আমরা npm এর একটি প্যাকেজ বেবহার করতে পারি, সেটা হচ্ছে env-cmd
npm i env-cmd --save-dev
devDependencies র জন্য --save-dev
এই ফ্ল্যাগ ব্যাবহার করা হয় কারণ এই মডিউলটি আমরা প্রডাকশনের জন্য ব্যাবহার করতে চাই না । একি ভাবে আমরা nodemon
ইন্সটল করার সময় ও ব্যাবহার করেছি কারণ nodemon
ও আমরা শুধুমাত্র development এর জন্য ব্যাবহার করবো । এখন প্রজেক্টের রুট ডিরেক্টরিতে config নামে একটি ডিরেক্টরি তৈরি করবো এবং এর আন্ডারে dev.env নামে একটি ফাইল তৈরি করবো এখানেই সকল environment variable গুলো রাখব । এখন package.json এ আমরা সামান্য একটি পরিবর্তন করবো dev এর জন্য ।
"scripts": {
"start": "node src/index.js",
"dev": "env-cmd -f ./config/dev.env nodemon src/index.js"
}
এখন dev.env ফাইলে নিচের লাইনটি লিখে environment variable তৈরি করবো ।
PORT=3000
index.js ফাইলে আমরা পোর্ট ফিল্টার করেছিলাম যে হয় process.env তে পোর্ট থাকবে আর না থাকলে 3000 এ পোর্ট kick start করবে । এখন যেহেতু আমরা dev.env ফাইলে environment variable এ পোর্ট দিয়ে দিয়েছি সেহেতু explicitly বলে দেওয়ার দরকার নাই । তাই সেটা বাদ দিয়ে দিবো ।
const port = process.env.PORT
এখন nodemon রান করলে এখান থেকে পোর্ট নিয়ে 3000 এ রান করবে ।
একি ভাবে আমরা mongodb র url টাও environment variable এ রাখব এবং token এর secret key টাও রাখবো ।
এজন্য mongoose.js ফাইলের mongodb র url টি dev.env ফাইলে রাখবো ।
MONGODB_URL=mongodb://127.0.0.1:27017/task-manager-api
আর mongoose.js ফাইলে ঐ লিঙ্কের জায়গায় process.env.MONGODB_URL লিখবো ।
এখন jwt token এর জন্য dev.env ফাইলে নিচের কোডটুকু লিখবো ।
JWT_SECRET=thisismysecret
আর যেখানে যেখানে ( routers/user.js, auth.js ) এই সেক্রেট ছিল ঐ জায়গাগুলোতে এটা দিয়ে দিবো (process.env.JWT_SECRET)
Creating production MongoDB database
mongodb database production এর জন্য অনেক ধরনের সল্যুশন আছে যেমন aws/google cloud/ azure ইত্যাদি কিন্তু mongodb কমিউনিটি ওদের নিজস্ব সল্যুশন আছে সেটা হচ্ছে Atlas
mongodb atlas এর সাইটে গেলে প্রথমে ক্লাস্টার তৈরি করতে বলবে । এখানে image-1 এ যা যা আছে সেগুলো ডিফল্ট রেখে প্রথমে ক্লাস্টার তৈরি করবো, এরপর cluster তৈরি হলে image-2 তে আসবে । এখান থেকে connect এ ক্লিক করে ip address সেট করে দিতে হবে ।
connect এ ক্লিক করার পর image-3 তে আসবে এখানে Add a Different IP Address
এ ক্লিক করার পর ip address সেট করে দিবো এখানে ip দিবো 0.0.0.0/0
অর্থাৎ সবার জন্য ওপেন থাকবে । ip দেওয়ার পর image-4 এ username এবং password দিয়ে Create Database User এ ক্লিক করবো ।
create user database এ ক্লিক করার পর ডাটাবেজের সাথে কানেক্ট করতে হবে সেজন্য এখানে অনেক কয়টা অপশন আছে সেখান থেকে Connect using MongoDB Compass এ ক্লিক করে compass .deb ফাইল ডাউনলোড করে ইন্সটল করে নিবো নিচের কমান্ডের সাহায্যে ।
sudo dpkg -i mongodb-compass_1.23.0_amd64.deb
এটা ইন্সটল করার সময় dependency প্রব্লেম দেখা দিলে dependency গুলো ইন্সটল করে নিবো ।
compass install হয়ে গেলে image-6 এ এই লিঙ্ক কপি করে নিয়ে এখানে <password> এর জায়গায় আমাদের পাসওয়ার্ড দিয়ে compass এ কানেক্ট করে নিবো ।
এখন এই ডাটাবেজ প্রডাকশনের জন্য ব্যাবহার করা যাবে ।
Heroku Deployment
Heroku তে deployment এর জন্য প্রথমে আমাদের গিটহাব repository তৈরি করতে হবে । এর জন্য প্রথমে SSH key জেনারেট করতে হবে আমাদের প্রোফাইলের সাথে সিকিউর কানেকশনের জন্য । এরজন্ন আমাদের আগের একটি ব্লগ আছে সেই আর্টিকেলের শেষের দিকে ssh key জেনারেট করার প্রসেস দেওয়া আছে ।
এরপর নিচের কমান্ড গুলো দিতে হবে ।
git init
গিট ইনিট হয়ে গেলে .gitignore
ফাইল তৈরি করে সেখানে বলে দিতে হবে কি কি ফাইল/ডিরেক্টরি আমরা গিটহাবে এড করতে চাচ্ছি না সেটা দিতে হবে । এই প্রজেক্টের জন্য node_modules, config ডিরেক্টরি চাচ্ছি না । তাই এই ফাইলে শুধু এই নাম দুটি দিয়ে দিলেই হবে এরপর সেভ করবো । এখন নিচের কমান্ড গুলো চালাবো ।
git add .
git commit -m "initialize git repository"
global config করা না থাকলে এটা কনফিগার করে নিবো ।
git config --global user.email "jahangir.droid@gmail.com"
git config --global user.name "jahangir_devs"
এরপর কমিট করবো ।
commit করার পর github এ গিয়ে একটি repository তৈরি করবো । এরপর নিচের কমান্ড গুলো চালিয়ে github এ আমাদের প্রজেক্ট push করবো ।
git remote add origin git@github.com:droidjahangir/nodejs-backend-solution.gitgit push -u origin main
এখন repository রিফ্রেশ করলে আমাদের প্রজেক্ট দেখাবে ।
All codes are here….
Heroku
আমাদের এই আর্টিকেলে গেলে শেষের দিকে heroku ইন্সটলেশনের ইন্সট্রাকশন দেওয়া আছে এবং ssh key, login এগুলোও দেওয়া আছে । এগুলো হওয়ার পর একটি নতুন app তৈরি করতে হবে ।
sudo snap install --classic heroku
heroku keys:add
heroku login
heroku create jahangir-nodejs-taskapp
এই এপের নাম unique হতে হবে পুরো heroku র মধ্যে ।
https://jahangir-nodejs-taskapp.herokuapp.com/
এটা হচ্ছে আমাদের heroku project লিঙ্ক ।
এখন আমাদের environment variable সেটআপ করতে হবে ।
heroku config:set key=value
heroku config
এখানে heroku config:set কমান্ডের মাধ্যমে আমরা environment variable সেট করে দিতে পারি ।
heroku config কমান্ডের মাধ্যমে আমরা দেখতে পারি কি কি env variable সেট আছে ।
heroku config:unset key এই কমান্ডের মাধ্যমে কোনও particular ভেরিয়েবল ডিলিট করে দিতে পারি । এখন আমরা আমাদের env ভেরিয়েবল সেট করবো ।
heroku config:set JWT_SECRET=thisismysecret
এই কমান্ডের মাধ্যমে একটি env variable সেটআপ করলাম । একাধিক env variable সেটআপ করার জন্য তাঁদের মাঝে স্পেস দিতে হবে । এখন আমরা mongoDB র url ভেরিয়েবলে সেট করবো । এরজন্য প্রথমে mongoDB atlas এর সাইটে গিয়ে লগইন করে connect এ ক্লিক করে login with application এ ক্লিক করলে নিচের মতো একটি pop-up উইন্ড আসবে এখানে থেকে এই url টি কপি করে নিয়ে যাবো ।
এখানে password এর জায়গায় আমাদের taskapp এর জন্য যে পাসওয়ার্ড টি ছিল ঐটি দিবো এবং dbname এর জায়গায় আমাদের ডাটাবেজের নাম দিবো । এরপর সেটাকে env variable এ সেট করবো ।
heroku config:set MONGODB_URL='mongodb+srv://taskapp:jahangirdevs@cluster0.53bqx.mongodb.net/task-manager-api?retryWrites=true&w=majority'
এখন এই কমান্ড দিয়ে env variable সেটআপ করবো এবং compass ওপেন করে নতুন একটি কানেকশন তৈরি করবো উপরের এই লিঙ্কটি দিয়ে ।
git push heroku master
এখন এই কমান্ডটি দিলে heroku তে প্রজেক্ট আপলোড হয়ে যাবে এবং রানিং অবস্থায় থাকবে ।postman এ গিয়ে প্রজেক্ট লিঙ্কে request করলে interact করা যাবে ।
https://jahangir-nodejs-taskapp.herokuapp.com/
আর mongoDB র clusters এ গিয়ে collection এ ক্লিক করলে আমাদের তৈরি করা task-manager-api ডাটাবেজটা দেখা যাবে এবং যা যা আপডেট করা হবে সকল কিছুই এখানে আপডেট থাকবে ।
এখন পোস্টম্যানে যেয়ে প্রডাকশন url সেটআপ করি এবং কিছু ইউজার এবং টাস্ক তৈরি করি । পরে get রিকোয়েস্ট ক্রে সেগুলো দেখতে পারবো ।
এভাবে আমরা production url সেটআপ করবো । url এর শেষে / এই চিহ্নটা কেটে দিবো ।
এরপর একটি ইউজার তৈরি করবো
{{url}}/users এ POST রিকোয়েস্ট করবো user data দিয়ে । ডাটা বেক চলে আসবে তাহলে বুঝতে হবে যে ইউজার তৈরি হয়ে গেছে । এখান থেকে আমরা সকল ধরনের রিকোয়েস্ট করতে পারবো ।
Mongodb Atlas এর cluster সেকশনের গিয়ে collection এ ক্লিক করলে আমরা আমাদের ডাটা দেখতে পারবো । অর্থাৎ আমাদের প্রজেক্ট এখন up and running হয়ে গেছে ।
এখন compass এ রিফ্রেশ করলে ডাটা চলে আসবে । লগইন করার পর read users অর্থাৎ সকল ইউজার দেখার জন্য compass এ গিয়ে user এর টোকেন কপি করে নিয়ে এসে postman এর bearar token এ এটা দিয়ে সেভ করলে এরপর সকল ডাটা দেখা যাবে এবং এখন authentic ইউজার হিশেবে সকল ধরনের অপারেশন চালাতে পারবো ।
happy coding….