জ্যাঙ্গো রেস্ট এপিআই সিরিজ(থার্ড পার্টি প্যাকেজ ছাড়া) পর্ব ১
“রেস্ট এপিআই” শব্দটারে সাথে আমরা সবাই কমবেশি পরিচিত। আর বর্তমানে অধিকাংশ ওয়েব এপ্লিকেশনে আমরা রেস্ট এপিআই নিয়ে কাজ করে থাকি। সাধারণত এপিআই তৈরী করা হয় ওয়েব রিসোর্স ম্যানেজ করার জন্য। হতে পারে মোবাইল এপ্লিকেশন দিয়ে কিংবা অন্য ওয়েব এপ্লিকেশন দিয়ে। সিম্পল ভাবে বললে দুইটি সফটওয়্যার এর মধ্যে সম্পর্ক স্থাপন এর জন্য যে সেতু তৈরী করা হয় সেটাই এপিআই (এপ্লিকেশন প্রোগ্রামিং ইন্টারফেস)। কিন্তু “রেস্ট” বলতে কী বুঝায়? REST (Representational State Transfer) হলো একটা সফটওয়ার আর্কিটেকচার যেখানে সিম্পল HTTP প্রটোকল দিয়েই ভিন্ন ভিন্ন ডিভাইসের মধ্যে যোগাযোগ স্থাপন, ডাটা আদান প্রদান করা যায়। যেমনঃ CRUD (Create, Read, Update, Delete) এর জন্য HTTP এর কমন মেথড গুলো হলো যথাক্রমেঃ Post, Get, Put, Delete !
এতক্ষণ বেসিক আলোচলা করলাম, এখন মূল প্রসঙ্গে আসি, সাধারণত আমরা Django Rest Framework দিয়ে এপিআই তৈরী করে থাকি। তবে চাইলে থার্ড পার্টি প্যাকেজ/ফ্রেমওয়ার্ক ছাড়াও আমরা পাইথন এর ডিফল্ট লাইব্রেরী এবং জ্যাঙ্গোর নিজস্ব কিছু ক্লাস, মেথড ব্যাবহার করে আমরা সহজেই এপিআই তৈরী করতে পারি। তবে প্রডাকশনে Django Rest Framework ব্যবহার করা উত্তম। এই আর্টিকেল মূলত এপিআই এর লজিক কীভাবে কাজ করে সেটা বোঝার জন্য লিখা হয়েছে।
ধরে নিলাম আপনার অলরেডি একটা প্রজেক্ট আছে, তো একটা সিম্পল এপ আমরা তৈরী করে নেই “persons” নামে। এবং প্রজেক্টের settings.py তে ইনক্লিউড করে নিতে হবে।
python manage.py startapp persons
আমরা অতি সিম্পল একটা মডেল নিয়ে কাজ করব। যেমনঃ
class Person(models.Model):
name = models.CharField(max_length=254)
email = models.EmailField(max_length=254,unique=True)
mobile = models.CharField(max_length=11) def __str__(self):
return self.name or ""
আপনি চাইলে এডিমিনে মডেলটি রেজিস্টার করে নিতে পারেন কিছু ডাটা পপুলেট করার জন্য মাইগ্রেট করার পর। যেহেতু আমরা JSON নিয়ে কাজ করব। তাই আমাদের ডাটা আগে JSON এ কনভার্ট করতে হবে। এ জন্য আমরা পাইথনের json লাইব্রেরীটা ব্যবহার করব।
import json #python's librarydef serialize(self): #called for a single instance data = {
"id" : self.id,
"name" : self.name,
"email" : self.email,
"mobile" : self.mobile
} response = json.dumps(data) #need python's json library return response
আমরা একটা মেথড তৈরী করলাম serialize নামে। data একটি পাইথন ডিকশোনারি যেখানে আমাদের মডেলের বিভিন্ন ফিল্ড গুলো Key:Value Pair এ দেয়া আছে। এখন রেস্পন্সে আমাদের ডিকশোনারি অবজেক্ট পাঠালে তো চলবে না, তাই পাইথন এর জেসন লাইব্রেরীর বিল্ট ইন মেথড json.dumps(data) দিয়ে আমরা পাইথন অবজেক্টকে জেসনে কনভার্ট করতে পারলাম। এটা সিংগেল ইন্সট্যান্সের ক্ষেত্রে কাজ করবে। আমরা আরো কাস্টমাইজ করতে মডেল ম্যানেজার দিয়ে মডেল কোয়ারীসেট ব্যবহার করব। নিচে models.py এর সম্পূর্ন জিস্ট দেয়া হলোঃ
class PersonManager(models.Manager):
def get_queryset(self):
return PersonQuerySet(self.model,using=self._db)
এখানে, PersonManager হচ্ছে, মডেল ম্যানেজার যেখানে এই মডেলের কোয়ারীসেটকে এটাচ করা হয়েছে। এবং প্যারামিটারে উক্ত মডেলের ইন্সট্যান্স এবং যে ডাটাবেসে অবস্থিত সেটার ইন্সট্যান্স পাঠানো হয়েছে।
class PersonQuerySet(models.QuerySet):
def serialize(self): #called when list of data is needed
response_list = list(self.values("id","name","email","mobile"))
return json.dumps(response_list)
এখানে, PersonQuerySet এ প্রথমে যেই ইন্সট্যান্স কিংবা অব্জেক্টই পাঠানো হোক না কেন, সেটার একটা লিস্ট তৈরী হবে, আর লিস্টের আইটেমগুলো পেতে আমরা self.values() মেথডটি ব্যবহার করছি। এটা মডেলের যে যে ফিল্ড আমাদের দরকার সেগুলো কোটেশনে কমা সেপারেটেড অবস্থায় দিতে হবে। এরপর আমরা জেসন ডাম্প করছি এই লিস্টটাকে যাতে জেসন আকারে রেসপন্স পাঠানো যায়।
এখন, মডেলে objects = PersonManager() দিয়ে আমরা মডেল ম্যানেজারকে মডেলের সাথে সংযুক্ত করেছি।
এখন আসি, ভিউ এর লজিক কেমন হবে? আমরা একটা ফোল্ডার তৈরী করব, “api” নামে persons এপে। এটাকে মডিউল হিসেবে সিস্টেমকে চেনাতে আমরা একটা empty ফাইল তৈরী করব __init__.py নামে এই “api” ফোল্ডারে ।
এখানে, আমরা দুটি Class Based View তৈরী করেছি। এবং CSRF প্রটেকশন উঠিয়ে দিতে একটা মিক্সিন তৈরী করা হয়েছে(অন্য কোন স্টোরিতে এটার ব্যাখ্যা করব)। যেহেতু Generic View ব্যবহার করা হয়েছে। তাই আমরা get() মেথডটি অভাররাইড করতে পারি।
class ListAPIView(CSRFExcemptHandler,View): #Disabled CSRF
def get(self, request, *args, **kwargs): #get all items
qs = Person.objects.all()
response = qs.serialize()
return HttpResponse(response,content_type='application/json')
উক্ত ভিউতে CSRFExcemptHandler, View দুটো ক্লাসকে এক্সটেন্ড করছে। এখন, get() মেথডে কোয়ারীসেট সিরিয়ালাইজ করে HttpResponse আকারে পাঠানো হচ্ছে। এখানে, HttpResponse() আমরা, জেসন ডাটা, কন্টেন্ট টাইপ, স্ট্যাটাস কোড প্যারামিটার আকারে দিতে পারি।
এখন আসি, সিংগেল ইন্সট্যান্স দেখতে হলে কি করা দরকার সেটার জন্য SingleApiView ক্লাসটির get() মেথডটি ব্যবহৃত হচ্ছে। এখানে শুধু প্যারামিটারে id পাস করা হয়েছে যারা মডেল থেকে ডাটা ফিল্টার করে আনা যায়। আর যদি না পাওয়া যায় তখন ইরর রেসপন্স দেয়া যায়।
এবার api ফোল্ডারে একটা urls.py ফাইল ক্রিয়েট করি। এবং নিচের কোডগুলো লিখি।
এখানে দুইটা ভিউ ইম্পোর্ট করা হয়েছে। এবং দুই ধরনের ইউআরএল প্যাটার্ন দেয়া হয়েছে।
বেজ ইউআরএল ListAPIView কে হিট করবে আর প্যারামিটার সহ ইউআরএলগুলো SingleApiView হিট করবে। তবে এখানে, http methods এর ধরন অনুযায়ী এই ভিউগুলোর স্পেসিফিক মেথডে হিট করবে।
এখন, মূল প্রজেক্টের urls.py তে এটা include করে নিতে হবে।
path('api/persons/', include('persons.api.urls')),
এখন ব্রাউজারে কিংবা পোস্টম্যানে http://localhost:8000/api/persons/
হিট করলে আপনি আপনার পার্সন মডেলের ডাটা জেসক ফরম্যাটে দেখতে পারবে, জেসন এরে আকারে।
আর http://localhost:8000/api/persons/<value of id>/ হিট করলে আপনি সিংগেল ইন্সট্যান্সের ডাটা জেসন ফরম্যাটে দেখতে পারবেন।
তো,দুধরনেরর GET রিকোয়েস্ট এর এপিআই এন্ডপয়েন্ট এর কাজ আপাতত হলো। এখন বাকী POST, PUT, DELETE এর কাজ করা। এখন আমরা দেখব, পোষ্ট মেথড কীভাবে কাজ করে। আমাদের একটা মডেল ফর্ম দরকার। তাই এপের ডিরেক্টোরিতে আমরা forms.py ফাইল ক্রিয়েট করি। নিচের কোডটি বেসিক ফর্ম সেটাপ। ভ্যালিডেশন লজিক আপনি আপনার মতো দিতে পারেন।
এখন আমাদের, বেজ ইউজ আর এল এ পোষ্ট মেথড এর জন্য মেথড তৈরী করতে হবে, ListAPIView তে post() ক্রিয়েট করি। এবং পাইথন অবজেক্ট জেসনে কনভার্ট পসিবল কিনা সেটার জন্য check() মেথড তৈরী করা হলো । অবশ্যই মডেল ফর্মটি ইম্পোর্ট করে নিতে হবে।
from persons.forms import PersonModelForm
এখন সবকিছু ঠিক থাকলে পোষ্ট রিকোয়েস্ট দিলে নতুন ডাটা ইনসার্ট হবে। এবং ইরর দিলে ইরর রেসপন্স স্পেসিফিক স্ট্যাটাস কোড সহ দেখাবে।
আগামী পর্বে আমরা দেখব, কীভাবে ডাটা আপডেট করা যাবে আর ডিলিট করা যাবে। এছাড়াও Unwanted HTTP Requests হ্যান্ডেল করার টেকনিক নিয়ে আলোচনা করব।
এই সিরিজের পর্ব ৩ থেকে আমরা Django Rest Framework নিয়ে কাজ করব।
ভুল ত্রুটি থাকলে অবশ্যই আমাকে কমেন্টে জানাবেন। এবং আপনাদের সাজেশন অবশ্যই জানাবেন।