Django REST Framework 101 พัฒนา API ด้วยภาษา Python

   By: Withoutcoffee Icantbedev

   อัปเดตล่าสุด Nov. 13, 2024

Django REST Framework 101 พัฒนา API ด้วยภาษา Python

Django REST Framework คือ Toolkit สำหรับทำ API ของ Python (Django) ซึ่งจะทำให้การพัฒนา RESTful API เป็นเรื่องง่าย เพราะว่ามีเครื่องมือครบครันในเฟรมเวิร์คตัวนี้ครบ โดยบทความนี้จะเป็นจุดเริ่มต้นให้ผู้อ่านไปต่อยอดในระดับสูงขึ้นได้ครับ

บทความแนะนำ: API คืออะไร หลักการทำงานของ API เป็นอย่างไร


รู้จักกับ Django REST Framework 

ก่อนที่เราจะไปเริ่มทำ API เราจะมาทำความรู้จักกับ Django REST Framework (DRF) กันก่อนครับ อย่างที่เกริ่นในด้านบนว่า DRF นั้นคือเฟรมเวิร์คของ Django อีกที เพราะว่า DRF นั้นอยู่บนพื้นฐานของ Django Framework รูปแบบการเขียน การขึ้นโปรเจคท์ในช่วงแรกนั้น มีความคล้ายคลึงกันค่อนข้างมาก  ดังนั้นก่อนที่จะใช้งานเฟรมเวิร์คนี้นั้น เราต้องมีพื้นฐาน Django มาก่อนครับ

ถ้ายังไม่มีพื้นฐาน Django แนะนำ: พัฒนาเว็บด้วย Django Framework ฉบับเต็มปี 2024



Django vs Django REST Framework

ความแตกต่างระหว่าง Django และ Django REST Framework คือ

Django 

Django REST Framework

คือ Web Framework

Web (API) Framework

ได้หน้าเว็บไซต์ (เว็บ devhub.in.th ที่เพื่อน ๆ กำลังอ่านตอนนี้ก็ใช้ Django ในการพัฒนาครับ)

ได้ API ที่เป็นข้อมูลแบบ JSON

SSR (Server Side Rendering)

API


RESTful API Concept

การทำ RESTful API นั้นจะอยู่บนพื้นฐาน HTTP Methods

HTTP Methods

คำอธิบาย

GET

ดึงข้อมูลแสดงผล

POST

บันทึกข้อมูล

PUT

แก้ไขข้อมูล

DELETE

ลบข้อมูล

PATCH

แก้ไขข้อมูล (บางส่วน)


1. Start API Project

เริ่มต้นสร้างโปรเจคท์ได้เลยครับ โดยสร้างโฟลเดอร์โปรเจคท์และสร้าง Virtual Environment ตามแบบฉบับของนักพัฒนา Python ได้เลย

$ mkdir && cd drf

# Virtual Environment
$ python3 -m venv env
$ source/bin/activate

# ติดตั้ง Django และ Django REST Framework
$ pip install django && rest_framework


ติดตั้ง Django REST

ติดตั้ง Django REST Framework

$ pip install django && rest_framework


Start Project & App

เริ่มต้นสร้างโปรเจคท์และแอปได้เลย เหมือนที่เราสร้าง Django App แบบปกตินั่นเองครับ

$ django-admin startproject drf .
$ python manage.py startapp api


ทำการเปิด VS Code แล้วอิมพอร์ตโปรเจคท์ของเราเข้ามาใน workspace ของ VS Code

โครงสร้างไฟล์ของโปรเจคท์


เพิ่ม App ใน settings

# drf/settings.py

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
...
...
'api', # App
'rest_framework' # Django REST App
]


2. API Models

ต่อมาจะเป็นการสร้าง Model เพื่อเก็บข้อมูล API ของเรา 

from django.db import models
from django.db.models.fields import BooleanField

class Task(models.Model):
title = models.CharField(max_length=80)
description = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now_add=True)
completed = models.BooleanField(default=False)

class Meta:
db_table = 'task'
ordering = ['-date_created']

def __str__(self):
return self.title


Update Database

ทำการอัพเดตฐานข้อมูลด้วยคำสั่งต่อไปนี้ 

$ python manage.py makemigrations
$ python manage.py migrate


3. Views

Views คือส่วนที่เราจะใช้ในการเขียนลอจิกหรือฟังก์ชันให้กับ API ของเรา 

from django.shortcuts import render
from .serializers import TaskSerializer
from .models import Task
from rest_framework import generics

class TaskListCreate(generics.ListCreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
class TaskDetailUpdateDelete(generics.RetrieveUpdateDestroyAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer


โค้ดส่วนอื่นจะคล้ายคลึงกัน แตกต่างกันตรงที่เราจะกำหนด action ให้กับ class ผ่าน  gererics  โมดูล จะได้

  •  gererics.ListCreateAPIView : สำหรับ Task List (ใช้แสดงผลและเพิ่ม Task) 
  •  gererics.Retrieve...APIView : สำหรับ Task Detail (ใช้แสดงผลแต่ละ Task รวมไปถึงการอัพเดตและลบ Task)

สำหรับ  gererics  โมดูลจะมี 5 เมธอดดังนี้

เมธอด

คำอธิบาย

 ListAPIView 

แสดงผล Task ทั้งหมด

 CreateAPIview

สร้าง Task ใหม่

 RetrievelAPIview 

แสดงผล Task นั้น ๆ

 UpdateAPIview 

 อัพเดต Task นั้น ๆ

 DeleteAPIview 

ลบ Task นั้น ๆ



4. Serializers

Serializers คือส่วนที่จะทำหน้าหน้าที่ในการแปลง Django Objects ไปเป็น JSON format เพราะว่าปกติในการทำ API เราก็ต้อง return ข้อมูลที่เป็น JSON ไปให้ฝั่ง Front-end ใช้งานต่อไป โดยในแอพของเรานั้นให้สร้างไฟล์ขึ้นมาอีก 1 ไฟล์ชื่อ    serializers.py  

# api/serializers.py

from rest_framework import serializers
from .models import Task

class TaskSerializer(serializers.ModelSerializer):

class Meta:
model = Task
fields = ('id', 'title', 'description', 'completed')



5. URL End-point

ต่อมาจะเป็นการสร้าง URL End-point ให้กับ API ของเราครับ โดยเราจะแบ่ง end-points ออกเป็น 2 ส่วน คือ

  • /api/tasks/ คือ URL ที่จะใช้สำหรับสร้างและแสดงผล Task ทั้งหมด
  • /api/tasks/<int:pk>/ คือ URL ที่จะใช้สำหรับ แสดงผล อัพเดตและลบ Task นั้น ๆ โดยเราจะอ้างอิงด้วย URL Parameter ที่เป็น ID นั่นก็คือ   /<int:pk> 
from django.contrib import admin
from django.urls import path, include
from api import views

urlpatterns = [
path('admin/', admin.site.urls),
path('api/tasks/', views.TaskListCreate.as_view()),
path('api/tasks/<int:pk>', views.TaskDetailUpdateDelete.as_view())
]


6. Browsable API

Browsable API คือ เครื่องมือในการทดสอบ API ที่มีมาให้กับ Django REST Framework เสร็จสรรพ เปรียบเสมือน Postman ย่อม ๆ ดี ๆ นี่เอง (แม้จะฟีเจอร์ไม่เยอะเหมือน Postman แต่ก็ทดสอบ API ในเบื้องต้นได้สะดวกดีเหมือนกันครับ) โดยลองเข้าไปที่ URL

http://127.0.0.1:8000/api/tasks/


ลองทดสอบเพิ่มข้อมูลเข้าไปได้เลยครับ


7. Authentication & Permissions

Authentication และ Permissions ก็มีมาให้เรียบร้อยใน Django โดยมีชื่อโมดูลว่า   permissions   สามารถอิมพอร์ตเข้ามาใช้งานได้เลยครับ

# api/views.py
...
from rest_framework import generics, permissions # New

class TaskListCreate(generics.ListCreateAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
# Authenticate this view
permission_classes = [permissions.IsAuthenticated]


เมื่อทดสอบกำหนด permission แล้วนั้นให้ลองรีเฟรชหน้าหน้าเดิมใน browsable API เมื่อสักครู่ที่ผ่านมา เราจะไม่สามารถเข้าได้ ต้องทำการ authen ก่อน



8. CORS 

CORS (Cross-Origin Resource Sharing) คือ การกำหนดสิทธิให้โดเมนไหนบ้างให้สามารถเข้าถึงหรือใช้งาน APIs ของเราได้ โดยการกำหนด CORS ใน Django REST Framework สามารถทำได้ดังนี้

ติดตั้ง Django CORS Header 

$ pip install django-cors-headers


ใช้งานโดยการ register app ใน  drf/settings.py 

INSTALLED_APPS = [
...,
"corsheaders",
...,
]


ติดตั้ง Middleware ที่เกี่ยวข้อง

MIDDLEWARE = [
...,
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...,
]


ตั้งค่า CORS

CORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:8000",
]


ซึ่งด้านบนก็คือโดเมนที่จะเข้าใช้ API ของเราได้ครับ (กำหนดได้ตามต้องการเลย)


ก็เป็นอันเสร็จสิ้นการทำ RESTful API ด้วย Python (Django REST Framework) กันเรียบร้อยครับ


9. ทดสอบ API Endpoint ใช้กับ Front-end (Vue.js)

หลังจากที่เราได้ API Endpoint แล้วเรียบร้อย ต่อมาก็จะทดสอบเชื่อมต่อ Endpoint ของเรากับ Front-end เฟรมเวิร์ค โดยในตัวอย่างนี้เราจะใช้ Vue.js ครับ

โดยในส่วนนี้จะไม่ได้ลงลึกถึงการอธิบายโค้ดส่วนต่าง ๆ ของ Vue (จะแยกเป็นอีกบทความ) โดยจะแสดงให้เห็นถึงกระบวนการในการเชื่อมต่อระหว่าง Back-end และ Front-end เท่านั้น

และแน่นอนว่าเราจะสร้างโปรเจคท์ Vue.js ด้วยการเรียกใช้ CDN จะไม่ได้สร้างด้วยท่ามาตรฐานอย่างการใช้ NPM ถ้าเพื่อน ๆ อยากเริ่มสร้างโปรเจคท์ Vue.js ตั้งแต่เริ่มต้น ก็สามารถศึกษาได้เพิ่มเติมจากบทความ พัฒนา web app ด้วย Vue.js สำหรับผู้เริ่มต้น 2023


นี่คือโค้ดครับ โดยเราจะใข้ Axios ซึ่งเป็นไลบรารียอดนิยมในการ request API ให้ทำการสร้างโฟลเดอร์ขึ้นมาใหม่ชื่อ "frontend" โดยในโฟลเดอร์นี้จะมีแค่ไฟล์ ๆ เดียวคือ "index.html" ที่เราจะใช้ในการสื่อสารกับ Back-end 

และ URL Endpoint ที่เราจะใช้คือ

http://127.0.0.1:8000/api/tasks/

โดย endpoint นี้ก็จะเก็บ tasks ต่าง ๆ ไว้ครับ


และนี่คือโค้ด HTML ทั้งหมด

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Endpoint Test with Vue.js and Django REST Framework | DH</title>
</head>
<body>
<div id="app">
<h1>Python (DRF) with Vue.js API Test</h1>
<button @click="fetchTasks">Fetch Tasks</button>
<ul v-if="tasks.length">
<li v-for="task in tasks" :key="task.id">{{ task.title }}</li>
</ul>
</div>

<!-- Vue.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<!-- Axios CDN -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script>
new Vue({
el: "#app",
data: {
tasks: [],
},
methods: {
fetchTasks() {
axios.get("http://127.0.0.1:8000/api/tasks/")
.then((response) => {
this.tasks = response.data;
})
.catch((error) => {
console.error("Error fetching tasks:", error);
});
},
},
});
</script>
</body>
</html>


ภาพรวมฝั่ง front-end แบบง่าย ๆ เลยครับ


โดยข้อมูลที่เราได้เพิ่มในฝั่ง Back-end ของ Django REST ตอนนี้จะเห็นว่ามีอยู่ 2 records (เพิ่มได้ตามต้องการ)

Tasks ที่ถูกเพิ่มเข้าไปในฐานข้อมูล แสดงผลในหน้า Browsable API


โดยฝั่ง Front-end ผมจะใช้ Go Live Extension ของ VS Code ซึ่งมันก็จะกำหนด Port มาให้

แบบนี้

http://127.0.0.1:5500/


ดึงข้อมูลจากฝั่ง Back-end สำเร็จ


Note: ในฝั่ง Back-end อย่าลืมตั้งค่า CORS ใน settings.py เพื่อกำหนดให้ Vue สามารถเรียกใช้ API ได้ด้วยการ allow origin (ไม่งั้นเราจะไม่สามารถ fetch ข้อมูลจากฝั่ง Back-end ได้)

CORS_ALLOWED_ORIGINS = [
...
"http://127.0.0.1:5500" # Vue (live server port in VS Code)
...
]


ก็เป็นอันเสร็จสิ้นการสร้าง API ด้วย Python Django REST Framework และทดสอบใช้งาน API ร่วมกับ Front-end อย่าง Vue.js หวังว่าบทความนี้คงเป็นประโยชน์ไม่มากก็น้อยนะครับ

ทาง devhub.in.th เราใช้ Django และ Django REST สำหรับเป็น back-end ในส่วนของ 📒 คอร์ส Full Stack Developer สามารถสอบถามรายละเอียดหรือลงทะเบียนได้เลยครับ


เปิดโลกการเขียนโปรแกรมและ Software Development ด้วย online courses ที่จะพาคุณอัพสกิลและพัฒนาสู่การเป็นมืออาชีพ เรียนออนไลน์ เรียนจากที่ไหนก็ได้ พร้อมซัพพอร์ตหลังเรียน

เรียนเขียนโปรแกรม

คอร์สเรียนแนะนำ

Full Stack Developer 2024

คอร์สเรียน Full Stack Developer 2024 ด้วยเฟรมเวิร์คยอดนิยมในการพัฒนา A…