Pengantar Django REST Framework
- Get link
- X
- Other Apps
Pengantar Django REST Framework
“Computer science empowers students to create the world of tomorrow.” - Satya Nadella, CEO of Microsoft
Di modul sebelumnya, Anda sudah mengetahui dasar dari web service dengan Django seperti database, migrations, package manager, dan membuat proyek dengan Django. Selain itu, Anda juga sudah berkenalan dengan REST Framework, bahkan melihat implementasinya.
Sesuai dengan nama modul, di modul ini kita akan mendalami REST Framework. Modul ini akan menjawab rasa penasaran Anda tentang REST Framework dengan membuat proyek RESTful API sederhana. Berikut adalah objektif pembelajaran yang akan dicapai pada modul kali ini.
- Mengidentifikasi kebutuhan RESTful API seperti fitur yang akan dibangun.
- Mengidentifikasi kebutuhan RESTful API yang akan dibangun
- Mengimplementasikan Django REST Framework untuk membuat proyek RESTful API.
- Menggunakan Serializers dan Deserializers untuk mengonversi tipe data.
- Mengklasifikasikan view di Django REST Framework
- Mengelompokkan routing di Django REST Framework
- Menggunakan Django Rest Framework dalam studi kasus RESTful API
Mari kita mulai!
Latihan: Membuat Proyek dengan Django REST Framework
Di modul sebelumnya, Anda sudah lihat sekilas implementasi dari REST Framework dan Anda sudah berhasil membuat proyek Django. Sebagian dari Anda mungkin sudah penasaran bagaimana cara membuat proyek dengan REST Framework. Oleh karena itu, ikuti langkah-langkah berikut ini untuk membuat proyek baru Django.
Pertama, buatlah folder baru dengan nama “drf-basic” (Anda dapat membuatnya di direktori apa pun).
- Kemudian, jalankan perintah berikut ini untuk memasang Django.
pipenv install django==4.2
- Setelah berhasil memasang Django, kita dapat membuat proyek Django dengan menjalankan perintah berikut ini.
django-admin startproject drf_project .
Perintah di atas akan membuat proyek baru di direktori saat ini, yaitu drf-basic. Berikut tampilan ketika menjalankan perintah untuk membuat proyek.
- Kemudian, buka proyek tersebut dengan PyCharm.
- Selanjutnya, untuk membuat Django app, jalankan perintah berikut ini.
django-admin startapp drf_app
Jika berhasil, Anda akan melihat folder baru yang bernama “drf_app”.
- Sekarang, pasanglah REST Framework dengan perintah berikut.
pipenv install djangorestframework
Tunggu hingga prosesnya selesai.

REST Framework merupakan sebuah Django app yang dapat digunakan kembali. Jika ingin menggunakan Django app, Anda harus mendaftarkannya di dalam INSTALLED_APPS. Anda masih ingat, kan?
- Untuk mendaftarkannya, buka berkas settings.py dan tambahkan dotted path dan rest_framework pada bagian paling atas INSTALLED_APPS.
INSTALLED_APPS = [ 'drf_app.apps.DrfAppConfig', 'rest_framework', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
Setelah itu, Anda dapat menjalankan server development.

Untuk menghilangkan pesan peringatan tersebut, hentikan server development dengan perintah CTRL + C dan jalankan migrations dengan perintah berikut.
python manage.py migrate
Selamat! Anda sudah berhasil membuat proyek dengan REST Framework terinstal. “Loh, bedanya apa dengan Django?” mungkin itulah pertanyaan yang akan Anda ajukan. Tenang, memang saat ini belum terlihat perbedaan antara keduanya. Anda baru merasakan “magis”nya REST Framework saat pengembangan RESTful API yang lebih kompleks.
Yuk, kita lanjut!
Django View
Di modul “Dasar-Dasar Web Service dengan Django” Anda sudah mengetahui pengertian dari view function. Selain itu, Anda juga sudah melihat implementasinya di Django. Di materi ini, kita akan melihat cara Django menangani view.
- Class Based View, Django memiliki view yang berbasis class seperti berikut.
- from django.views import View
- from django.http import HttpResponse
- class HelloWorldView(View):
- def get(self, request):
- return HttpResponse("Hello World")
- Function Based View, Django memiliki view yang berbasis function seperti contoh berikut.
- from django.http import HttpResponse
- def hello_world_view(request):
- return HttpResponse("Hello World")
Nah, bagaimana jika kita menggunakan REST framework? REST framework menyediakan dua pendekatan utama: Class-Based View dan Function-Based View.
- Pada Class-Based View, REST framework akan meng-extend
APIView. - Pada Function-Based View, REST framework menggunakan API View Decorator.
Penasaran dengan API View Decorator? Yuk, simak materi selanjutnya!
API View Decorator
Masih ingatkah Anda di modul sebelumnya ada sintaks @api_view di dalam view function? Jika tidak, mari kita lihat kembali cuplikan kode view function sebelumnya.
- dari rest_framework.decorators impor api_view rest_framework.decorators import api_view
- from rest_framework.response import Response
- @api_view()
- def movies(request):
- if request.method == 'GET':
- response = '{ "movies": ["Agak Laen", "Warkop DKI Reborn Part 1", "Pengabdi Setan 2", "Dilan", "Sewu Dino"] }'
- return Response(response)
Di contoh kode tersebut, terdapat API decorator yaitu @api_view(). Di Python, decorator adalah function yang dapat menambah fungsionalitas yang sudah ada tanpa mengubah implementasi kodenya. Untuk mengulang kembali, Anda dapat mengunjungi materinya di kelas Memulai Pemrograman dengan Python.
Sehingga dalam konteks REST Framework, API decorator adalah decorator yang akan membaca HTTP method yang harus diresponse oleh view function. Secara bawaan, API decorator dapat membaca HTTP method GET. Jika ingin menggunakan HTTP method lainnya, Anda harus menuliskannya secara eksplisit. Berikut contohnya:
- @api_view(['GET', 'POST', 'PUT', 'DELETE'])(['GET', 'POST', 'PUT', 'DELETE'])
Jika mengirimkan HTTP request ke method yang tidak ada di daftar tersebut, REST Framework akan mengembalikan response 405 (method not allowed). API decorator secara umum digunakan untuk pengembangan dengan paradigma function based view. Selain itu, API decorator juga dapat digunakan berbarengan dengan decorator lainnya seperti permissions. Berikut contohnya.
- @api_view()()
- @permission_classes([IsAuthenticated])
- def movies(request):
- response = '{ "movies": ["Agak Laen", "Warkop DKI Reborn Part 1", "Pengabdi Setan 2", "Dilan", "Sewu Dino"] }'
- return Response(response)
Decorator permissions digunakan untuk memproteksi endpoint atau URL. Pada contoh di atas, view function movies akan diproteksi oleh decorator permissions sehingga untuk mengaksesnya kita harus login terlebih dahulu. Untuk melihat daftar decorator yang tersedia, Anda dapat mengunjungi halaman dokumentasi REST Framework.
Lihatlah magisnya! Fitur dari REST yang kita butuhkan, dapat terpenuhi dengan hanya menambahkan decorator masing-masing.
Serializers
Mari kita mulai dengan sebuah analogi. Misalkan, Anda memiliki teman orang Timor Leste yang hanya bisa berbahasa Portugis. Ketika berbicara dengannya, Anda membutuhkan seorang penerjemah. Anda akan menyampaikan ke penerjemah dalam bahasa Indonesia dan penerjemah akan menerjemahkan ke bahasa Portugis agar dipahami oleh teman. Itulah analogi serializer.
Konversi data merupakan proses yang penting dilakukan saat pengembangan API. Kenapa penting? Hal tersebut karena data yang kita olah tidak mungkin selalu berformat sama. Misalnya, data yang dikirimkan client bisa dalam format text plain, JSON, atau data yang ada di database berformat tipe data native Python. Nah, tentunya kita perlu suatu proses yang dapat mengonversi data. Bagaimana caranya?
Berkenalan dengan Serializers
Serializers merupakan fitur populer yang ada di REST Framework. Serializers adalah cara untuk mengonversi data yang kompleks seperti model menjadi data yang bertipe data native Python. Ketika data tersebut sudah menjadi tipe data native Python, akan lebih mudah untuk mengubahnya menjadi JSON atau XML.

Serializer dapat mengontrol keluaran atau response yang ingin diberikan ke client. Agar data konsisten, serializer memiliki validasi data.
Untuk membuat serializer, kita harus menambahkan berkas baru bernama serializers.py di dalam Django app. Serializer dapat didefinisikan dengan mudah. Misalnya, membuat serializer untuk resources produk seperti berikut.
- from rest_framework import serializers
- class ProductSerializer(serializers.Serializer):
- name = serializers.CharField(max_length=200)
- price = serializers.IntegerField()
- category = serializers.CharField(max_length=200)
Di dalam serializer, atribut yang ada di resources produk akan ditulis seperti name, price, dan category.
Setelah itu, tambahkan objek Product di atas class ProductSerializer.
- class Product:
- def __init__(self, name, price, category):
- self.name = name
- self.price = price
- self.category = category
Class Product digunakan hanya untuk contoh saat ini. Berikut kode lengkap serializers.py
- from rest_framework import serializers
- class Product:
- def __init__(self, name, price, category):
- self.name = name
- self.price = price
- self.category = category
- class ProductSerializer(serializers.Serializer):
- name = serializers.CharField(max_length=200)
- price = serializers.IntegerField()
- category = serializers.CharField(max_length=200)
Kemudian, di dalam view Anda dapat memanggil serializer seperti berikut.
- from rest_framework.decorators import api_view
- from rest_framework.response import Response
- from first_app.serializers import ProductSerializer, Product
- @api_view()
- def products(request):
- product = Product(name="Celana Bayi", price=200000, category="Fashion")
- serializer = ProductSerializer(product)
- return Response(serializer.data)
View tersebut akan mengembalikan response dengan data produk seperti hasil di bawah ini.

Setelah memahami bagaimana melakukan validasi data di dalam serializer, selanjutnya adalah mengenal jenis-jenis serializer yang tersedia di REST Framework.
Model Serializer
Model serializer adalah jenis serializer yang paling sering digunakan. Model serializer merupakan serializer yang memudahkan kita untuk mengonversi data dari model. Model serializer cocok digunakan ketika bekerja dengan model di Django. Dengan menggunakannya, Anda tidak perlu mendefinisikan satu per satu atribut dari data beserta tipe datanya di dalam serializers. Jika di contoh sebelumnya, Anda menuliskan serializer seperti berikut.
- class ProductSerializer(serializers.Serializer):
- name = serializers.CharField(max_length=200)
- price = serializers.IntegerField()
- category = serializers.CharField(max_length=200)
Dengan menggunakan model serializer, Anda cukup menuliskannya seperti berikut.
- class ProductSerializer(serializers.ModelSerializer):
- class Meta:
- model = Product
- fields = ['name', 'price', 'category']
Di dalam class ProductSerializer, kita memberikan argumen ModelSerializer. Kemudian, di dalamnya terdapat Class Meta. Class Meta berfungsi untuk mendefinisikan model yang akan digunakan dan juga atribut mana yang akan diserialisasi. Anda dapat dengan mudah untuk memilih atribut apa saja yang ingin ditampilkan dengan cara mengubah fields yang ada di dalam class Meta.
Serializer Relations
Ketika Anda sudah berinteraksi dengan database dan model, di mana antar tabel sering memiliki relasi, Anda akan membutuhkan relationship serializer. Relationship serializer akan menampilkan data yang memiliki relasi dengan resources saat ini.
Misalnya, Anda ingin menampilkan keranjang beserta produk. Berikut contoh implementasinya.
- class CartSerializer(serializers.ModelSerializer):
- product = ProductSerializer()
- class Meta:
- model = Cart
- fields = ['id', 'product', 'quantity']
Di dalam CartSerializer, ada satu field bernama product, yang berisikan ProductSerializer. Artinya, saat menampilkan data keranjang, response yang diberikan tidak hanya menampilkan ID produk, tetapi kita juga akan menampilkan informasi lengkap tentang produk tersebut.
Selain menggunakan cara tersebut, kita juga dapat menggunakan cara berikut.
- class CartItemSerializer(serializers.ModelSerializer):
- product = serializers.StringRelatedField()
- class Meta:
- model = Cart
- fields = ['id', 'product', 'quantity']
Cara di atas menggunakan StringRelatedField(). Dengan menggunakan StringRelatedField, data yang ditampilkan hanya data sederhana, misalnya name tanpa mengembalikan seluruh detail dari objek tersebut. Beda halnya dengan ProductSerializer() sebelumnya yang menampilkan seluruh data detail dari objek produk.
Hyperlink Model Serializer
Hyperlink model serializer mirip dengan relationship serializer. Perbedaannya adalah jika di relationship serializer menggunakan foreign key atau relasi tabel, hyperlink akan merepresentasikan hubungan resources dalam bentuk link.
Misalnya, ketika menampilkan data, kita bisa menggunakan contoh di bawah ini.
- class ProductSerializer(serializers.HyperlinkedModelSerializer):
- user = serializers.HyperlinkedRelatedField(
- view_name='user-detail',
- read_only=True
- )
- class Meta:
- model = Product
- fields = ['url', 'name', 'price', 'category', 'user']
Di dalam ProductSerializer terdapat atribut user yang berisi hyperlink (link yang dapat diklik). Kemudian, di dalam fields di class Meta terdapat atribut user dan url. user digunakan untuk menampung link yang menuju ke user terkait, sedangkan url berisi link yang menuju ke produk.
Misalkan Anda memiliki sebuah produk dengan nama "Baju anak-anak", harga 200 ribu rupiah, kategori "Fashion", dan dimiliki oleh seorang user dengan ID 1. Ketika dijalankan, hasilnya akan terlihat seperti berikut.

Sekarang, yuk kita lanjut ke materi berikutnya!
Catatan:
Untuk menggunakan Model, Relationship dan Hyperlink Serializer, Anda harus menggunakan Django model.
Deserializers
Setelah memahami cara serializer bekerja untuk mengubah data Python menjadi format yang bisa dikirim sebagai response, seperti JSON, selanjutnya adalah membahas kebalikannya, yaitu deserializer. Deserializer adalah kebalikan dari serializer dan deserializer terjadi saat client mengirimkan data melalui HTTP POST. Deserializer akan merutekan data tersebut ke model yang ada. Deserializer berfungsi untuk mengonversi data dari format JSON ke model.
Untuk membuat deserializer, kita tidak perlu membuat berkas baru seperti serializer. Misalnya, untuk menerima data produk baru dari client, Anda cukup untuk menuliskannya seperti berikut.
- @api_view(['GET', 'POST'])
- def products(request):
- if request.method == 'GET':
- product = Product(name="Celana Bayi", price=200000, category="Fashion")
- serializer = ProductSerializer(product)
- return Response(serializer.data)
- elif request.method == 'POST':
- serializer = ProductSerializer(data=request.data)
- return Response(serializer.data)
Loh, apa perbedaannya dengan serializer? Perbedaannya adalah argumen yang ada saat deserializer merupakan data yang berasal dari request body. Kemudian, data yang diterima akan divalidasi terlebih dahulu sebelum disimpan atau diolah lebih lanjut.
Lalu, bagaimana cara untuk validasi data? Misalnya, validasi data produk yang dikirimkan client atau pengguna melalui HTTP POST. Perhatikan kode berikut.
- @api_view(['GET', 'POST'])
- def products(request):
- if request.method == 'GET':
- product = Product(name="Celana Bayi", price=200000, category="Fashion")
- serializer = ProductSerializer(product)
- return Response(serializer.data)
- elif request.method == 'POST':
- serializer = ProductSerializer(data=request.data)
- serializer.is_valid(raise_exception=True)
- return Response(serializer.data)
Di blok kode POST, method is_valid() akan dipanggil untuk memvalidasi data. Di dalam is_valid() terdapat argumen yang berfungsi untuk mengembalikan exception ketika data yang dikirim tidak valid. Misalnya, mengirimkan data yang kosong, exception akan bangkit. Ketika mengirimkan data yang kosong atau tidak lolos validasi, Anda akan melihat tampilan seperti berikut.

Begitulah cara serializer untuk memvalidasi data request. Dengan begitu, data yang masuk adalah data yang bersih dan konsisten karena sudah melewati tahapan validasi. Mari kita lanjut. Semangat ya!
Function Based View
Sebelum ini, Anda sudah tahu cara kerjanya serializers dan deserializers. Serializers dan deserializers digunakan pada view function. Salah satu view function yang tersedia di Django adalah function based view.
Function based view (FBV) adalah cara mendefinisikan view di Django menggunakan fungsi Python biasa. Function based view menggunakan function Python biasa untuk menerima request dan mengembalikan response. Function based view menggunakan class Request milik REST Framework untuk menerima HTTP request (bukan class HttpRequest milik Django). Untuk mengembalikan response ke client, function based view menggunakan class Response milik REST Framework (bukan HttpResponse milik Django).

Function based view memiliki kelebihan yaitu gampang untuk diterapkan karena merupakan function Python biasa dan mudah untuk dibaca. Selain itu, function based view memudahkan ketika ingin menggunakan decorator (kita sudah lihat contoh decorator sebelum ini).
Berikut contoh penerapan function based view.
- from rest_framework.decorators import api_view
- from rest_framework.response import Response
- @api_view()
- def hello_world(request):
- return Response({"message": "Hello, world!"})
Function hello_world mengembalikan class Response milik REST Framework. Class Response memungkinkan kita untuk mendapatkan fitur dari REST framework yaitu browsable API.

Seperti yang dijelaskan sebelumnya, penggunaan function based view sangat mudah. Setelah menuliskan view function, kita akan membuat routing di urls.py. Berikut contoh kode urls.py di Django app.
- from django.urls import path
- from . import views
- urlpatterns = [
- path("", views.hello_world),
- ]
Di dalam urls.py, Anda cukup menuliskan nama function-nya saja seperti contoh di atas. Boom! Anda sudah berhasil menerima HTTP request dan memberikan response. Bagaimana, sederhana, kan?
Kita coba lihat contoh implementasi function based view di RESTful API. Misalnya, RESTful API yang menampilkan daftar suatu produk seperti berikut ini.
- @api_view(['GET', 'POST'])
- def product_list(request):
- if request.method == 'GET':
- products = Product.objects.all()
- serializer = ProductSerializer(products, many=True)
- return Response(serializer.data)
- elif request.method == 'POST':
- serializer = ProductSerializer(data=request.data)
- if serializer.is_valid():
- serializer.save()
- return Response(serializer.data, status=status.HTTP_201_CREATED)
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Jangan khawatir jika Anda tidak memahami beberapa bagian kode di atas karena nanti akan kita bahas juga, ya! Kita akan coba bahas beberapa bagian kode. Perhatikan kode bagian berikut.
- @api_view(['GET', 'POST'])
Kode tersebut digunakan untuk memberitahu view untuk menerima HTTP request dengan method GET dan POST. Kemudian, di dalam function product_list, terdapat blok if-else. Jika method-nya adalah GET, blok if pertama akan dijalankan. Jika method-nya adalah POST, blok if kedua akan dijalankan.
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Kode di atas digunakan untuk memberikan response. Di dalam class Response terdapat status yang digunakan untuk memberikan status code di response (masih ingat, kan, materi di modul Dasar-Dasar Web Service dengan Django?).
Wah, ternyata kode yang kita tulis lumayan panjang, ya? Apakah tidak ada cara yang lebih ringkas untuk menuliskan view function? Untuk mengetahui jawabannya, jangan lupa untuk lanjut modul berikutnya!
Class Based View
Jika sebelumnya Anda sudah mengenal function based view, sekarang Anda akan berkenalan dengan class based view. Ayo kita mulai!
Class based view adalah view yang mewarisi (inheritance) class APIView milik REST Framework. Penggunaan APIView hampir sama seperti view biasanya, HTTP request yang masuk akan diterima dan diproses hingga memberikan response. Class based view juga menggunakan class Request dan Response, sama seperti Function based view.
Kelebihan dari class based view yaitu mengurangi kode yang ditulis sehingga duplikasi kode berkurang. Selain itu, kita dapat menulis function yang berbeda di dalamnya sesuai dengan HTTP method seperti POST, GET, DELETE, dan sebagainya.
Berikut contoh sederhana penggunaan Class based view.
- from rest_framework.views import APIView
- from rest_framework.response import Response
- class HelloWorldView(APIView):
- def get(self, request):
- return Response({"message": "Hello, world!"})
Sesuai dengan namanya, pada contoh di atas, kita mengawali dengan menuliskan class dan diikuti dengan nama classnya. Kemudian, di dalam class tersebut, kita memberikan argumen APIView dan menuliskan function get. Function get digunakan untuk menangani HTTP request GET.
Kemudian, untuk penulisan di urls.py Django app sedikit berbeda dengan function based view. Perhatikan contoh urls.py berikut.
- from django.urls import path
- from . import views
- urlpatterns = [
- path("", views.HelloWorldView.as_view()),
- ]
Di dalam urlpatterns, untuk view function yang class based ditulis berbeda dengan function based. Untuk class based, kita akan memanggil nama class-nya dan diikuti dengan as_view(). as_view() adalah method yang ada di dalam class APIView untuk mengonversi class menjadi view function.
Ketika dijalankan, hasilnya masih sama seperti function based view.

Mari kita lihat contoh implementasi class based view di RESTful API. Masih ingat, kan, RESTful API yang menampilkan daftar produk sebelumya? Berikut implementasinya jika menggunakan class based view.
- class ProductList(APIView):
- def get(self, request):
- queryset = Product.objects.all()
- serializer = ProductSerializer(queryset, many=True)
- return Response(serializer.data)
- def post(self, request, format=None):
- serializer = ProductSerializer(data=request.data)
- if serializer.is_valid(raise_exception=True):
- serializer.save()
- return Response(serializer.data, status=status.HTTP_201_CREATED)
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Pada contoh di atas, kita sudah tidak menggunakan API decorator. Selain itu, alih-alih menggunakan blok if-else, kita memisahkannya menjadi dua function terpisah. Function tersebut adalah get dan post.
Kemudian, kita coba bahas bagian kode berikut.
- def get(self, request):
- queryset = Product.objects.all()
- serializer = ProductSerializer(queryset, many=True)
- return Response(serializer.data)
Di dalam function get, kita memberikan dua argumen. Yang pertama adalah self yang digunakan untuk merujuk ke instance class ProductList. Lalu, argumen kedua adalah request yang digunakan untuk mengakses class Request.
Sebenarnya, ada berbagai macam cara untuk menuliskan view di REST framework. Beberapa di antaranya sudah dijelaskan seperti function dan class based view. Namun, untuk view lainnya, kita tidak akan bahas saat ini karena hal tersebut sudah merupakan level mahir.
ViewSet
Saat ini, Anda sudah bisa mengetahui tentang view function di Django yaitu function based view dan class based view. Selanjutnya, kita akan membahas tentang ViewSet.
ViewSet adalah jenis view function yang merupakan bagian dari class based view dan sama-sama berbasis class. Perbedaannya dengan class based view adalah ViewSet tidak menyediakan fungsi seperti .get(), .post() dan sebagainya. Sebagai gantinya, ViewSet menyediakan fungsi seperti create(), list(), update(), dan sebagainya. Di dalam ViewSet memungkinkan kita untuk menggabungkan logika CRUD (Create, Read, Update, Delete) yang ada di view dalam satu class.
Mari kita lihat contoh implementasinya. Misalnya, untuk menampilkan daftar produk, contoh kodenya akan tampak seperti berikut ini.
- kelas ProductViewSet(viewsets.ViewSet):
- def list(self, request):
- produk = Produk(nama="Celana Bayi", harga=200000, kategori="Mode")
- Serializer = ProductSerializer(product)
- kembalikan Respons(serializer.data)
Dengan menggunakan ViewSet, view function Anda akan terlihat lebih terstruktur dan mudah untuk dibaca. Pada contoh di atas, view function ditulis dengan sintaks class dan diikuti dengan namanya. Kini, decorator @api_view sudah tidak diperlukan. Selain itu, perhatikan argumen yang diberikan, saat ini argumen yang diberikan adalah ViewSet. Kemudian, di dalamnya terdapat function list, list digunakan untuk menampilkan daftar produk. Selain list, terdapat function lainnya. Berikut adalah function yang tersedia di ViewSet.
- def list()
- def create()
- def retrieve()
- def update()
- def partial_update()
- def destroy()
Ada sedikit perbedaan di bagian urls.py. Biasanya, di urls.py akan memanggil nama view function seperti berikut.
- dari django.urls impor jalur
- dari . impor tampilan
- urlpatterns = [
- jalur("", tampilan.produk),
- ]
Ketika menerapkan ViewSet, urls.py akan ditulis seperti berikut.
- dari django.urls impor jalur
- dari .views impor ProductViewSet
- urlpatterns = [
- jalur("", ProductViewSet.as_view({'get': 'list'}), nama='daftar-produk'),
- ]
ViewSet dipanggil dan diikuti dengan method .as_view(). Method as_view() bertujuan untuk menghubungkan method HTTP dengan method di dalam kelas. Misalnya, method HTTP GET akan dihubungkan dengan method list yang ada di dalam ProductViewSet.
Ketika dijalankan, hasilnya akan tampak seperti berikut.
Catatan:
Contoh di atas merupakan cara yang tidak dianjurkan karena ketika menggunakan ViewSet, URL tidak akan didaftarkan secara eksplisit. Simak materi setelah ini ya untuk membahas tentang routing!
Routing
Sebelumnya, kita telah melihat cara implementasi routing (perutean) dilakukan di urls.py. Routing sendiri adalah teknik yang digunakan untuk menghubungkan URL dengan tampilan halaman web atau endpoint RESTful API. Di modul ini, kita akan bahas lebih lanjut tentang routing di Django.
Ketika menggunakan ViewSet, disarankan untuk menggunakan router agar tidak perlu menulis URL secara eksplisit satu per satu. REST Framework memiliki beberapa jenis router. Mari simak pembahasannya di bawah ini.
Simple Router
Simple router adalah jenis router yang sangat sederhana dan mudah untuk diterapkan. SimpleRouter() memiliki route standar untuk function list, create, retrieve, update, partial_update, dan destroy sehingga Anda tidak perlu mendefinisikan URL satu per satu untuk setiap aksi. Berikut adalah contoh implementasi dari simple router.
- from rest_framework import routers
- from first_app.views import ProductViewSet
- router = routers.SimpleRouter()
- router.register('products', ProductViewSet, basename='product')
- urlpatterns = router.urls
Pada contoh di atas, yang pertama dilakukan adalah menuliskan router yang di dalamnya terdapat SimpleRouter(). Kemudian, mendaftarkan ProductViewSet ke router dengan method register(). Method register() memiliki beberapa argumen seperti suffix (‘products’), nama ViewSet (ProductViewSet), dan basename yang akan menjadi dasar untuk nama URL yang dibuat. Setelah itu, urlpatterns berisi semua route yang terdaftar.
Ketika dijalankan (masih menggunakan kode sebelumnya), hasilnya akan tampak seperti berikut ini.

Default Router
Router jenis ini sama seperti simple router tapi memiliki dua fitur tambahan yaitu API root view dan route opsional dengan format .json. Mari kita bahas kedua fitur tersebut.
Yang pertama, API root view. Fitur API root view dapat diakses dengan mengunjungi root URL dari proyek. Misalnya, root proyek saat ini adalah http://localhost:8000/. Ketika mengakses halaman tersebut, akan tampak hasil seperti berikut.

API root view dapat membantu kita untuk melihat apa saja endpoint atau resources yang tersedia di proyek saat ini.
Kedua, terdapat opsional route yang berformat .json. Untuk dapat menggunakan fitur ini, tambahkan argument format=None di function dalam ViewSet.
- class ProductViewSet(viewsets.ViewSet):
- def list(self, request, format=None):
- queryset = products_data # Menggunakan data produk dari luar
- serializer = ProductSerializer(queryset, many=True) # Menyertakan many=True
- return Response(serializer.data)
Kemudian, akses URL dengan menambahkan .json di akhirnya seperti http://localhost:8000/products.json. Anda akan melihat hasil seperti berikut ini.
Response yang memiliki format JSON dapat digunakan untuk kebutuhan client seperti untuk menampilkan data di tampilan Front-End. Saat ini, kita sudah mengetahui dua jenis router di REST Framework. Selanjutnya, kita akan latihan untuk menerapkan pengetahuan yang sudah didapat di sebuah studi kasus RESTful API sederhana.
Let’s go!
Django Model
Dalam pengembangan aplikasi, penyimpanan dan pengelolaan data sangat diperlukan. Pada studi kasus aplikasi catatan, kita pasti butuh untuk menyimpan data catatan, melihat, dan menghapusnya. Oleh karena itu, kita akan menggunakan database untuk menyimpan datanya.
Ketika membicarakan database, kita butuh cara yang dapat mempermudah interaksi antara aplikasi dan database. Selain itu, sebelum menggunakannya, kita harus mendefinisikan data yang ingin disimpan. Untuk mendukung hal itu, di Django, terdapat Django model.
Model adalah objects yang menjadi sumber informasi tentang data yang digunakan di aplikasi. Di dalam model terdapat informasi yang penting seperti atribut yang dimiliki oleh data. Biasanya, setiap model akan ditujukan ke satu tabel yang ada di Database. Setiap atribut yang ada di model, merepresentasikan atribut yang ada di Database.
Misalnya, membuat model untuk sebuah buku. Buku memiliki atribut judul, tahun terbit dan penulis. Berikut contoh model buku.
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=30)
publish_date = models.IntegerField()
author = models.CharField(max_length=50)Untuk membuat model, diawali dengan menulis class, kemudian nama modelnya. Setelah itu, di dalam class Book kita memberikan argumen yang merupakan class Model milik Django. Di dalam class Book, terdapat definisi dari atribut data. Misalnya, title dengan tipe data char. Untuk melihat tipe data apa saja yang didukung di model, Anda dapat mengunjungi halaman dokumentasi fields Django.
Model di atas jika dijalankan, akan menghasilkan SQL untuk membuat tabel seperti berikut.
CREATE TABLE myapp_book ( "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "title" varchar(30) NOT NULL, "publish_date" date NOT NULL, "author" varchar(50) NOT NULL );
Setelah membuat model, Anda dapat memanggilnya di dalam Django app dengan cara mengimpornya menggunakan format berikut.
from <nama_app>.models import <nama model>
Contohnya seperti berikut.
from my_app.models import Book
Bagaimana, mudah, kan? Di materi selanjutnya, kita akan praktik melalui studi kasus.
Studi Kasus Membuat RESTful API dengan DRF
Dari modul 2 hingga saat ini, Anda telah mempelajari banyak hal tentang REST Framework. Kita telah membahas cara Django menerima HTTP request, memberikan response, menggunakan View Function, bekerja dengan Serializers, hingga memahami konsep routing. Dengan berbekal pengetahuan ini, kini saatnya kita melangkah lebih jauh ke tahap yang lebih praktis, yaitu membangun RESTful API melalui studi kasus aplikasi catatan.
Mengidentifikasi Kebutuhan RESTful API
Seperti yang Anda ketahui, kita akan membuat RESTful API aplikasi catatan sederhana. Namun, sebelum itu, kita akan menganalisis kebutuhan atau kriteria dari proyek tersebut. Ayo kita identifikasi bersama!
- Tools yang dibutuhkan
Untuk membuat RESTful API dengan Django, kita membutuhkan tools seperti Django, REST Framework, PIP, Pipenv, dan IDE. Saat ini, kita sudah memenuhi kebutuhan tersebut.
- Kriteria Proyek
Kita akan membangun RESTful API untuk aplikasi catatan sederhana. Agar tujuan kita tercapai, kita membutuhkan aplikasi yang berfungsi berfungsi untuk menyimpan (create), melihat (read), mengubah (update), dan menghapus (delete) catatan. Fungsionalitas ini dikenal sebagai operasi CRUD.
- Struktur Proyek
Alangkah lebih baik jika sebelum mengembangkan RESTful API untuk menyusun struktur proyek terlebih dahulu agar pengembangan mudah dilakukan. Mengembangkan RESTful API dengan Django akan menarik karena Django dapat memisahkan proyek menjadi Django app. Struktur proyek yang akan kita buat kurang lebih seperti berikut ini.
Anda dapat mengabaikan berkas yang kurang relevan seperti External Libraries dan Scratches and Consoles. Cukup fokus pada folder notes dan notes_app_back_end.
Itulah kebutuhan yang harus kita penuhi untuk membuat RESTful API aplikasi catatan dengan Django. Di materi selanjutnya, kita akan mulai merincikan kriteria dari proyek aplikasi catatan. Yuk, kita lanjut!
Kriteria RESTful API Aplikasi Catatan
Karena kebutuhan pertama tentang tools sudah terpenuhi dan struktur proyek, sekarang kita akan langsung bahas kebutuhan selanjutnya yaitu kriteria proyek. Apa saja kriterianya? Yuk, simak penjelasan berikut.
Kriteria 1 - RESTful API menyediakan cara untuk menyimpan catatan
Kriteria pertama adalah RESTful API menyediakan cara menyimpan catatan baru melalui HTTP request.
Berikut struktur dari objek catatan yang perlu disimpan oleh aplikasi.
- {
- id: string,
- judul: string,
- createdAt: string,
- updatedAt: string,
- tag: larik string,
- isi: string
- },
Berikut contoh response dari web server dengan data sesungguhnya.
- {
- "id": "4dcc2652-064a-41e3-932b-9939d290f408",
- "title": "Catatan pertama saya",
- "body": "Ini adalah contoh catatan saya dalam perjalanan belajar Back-End dengan Django di Dicoding",
- "tag": [
- "Pribadi"
- ],
- "dibuat pada": "2024-11-25T09:05:02.481059Z",
- "updatedAt": "2024-11-25T09:05:02.481106Z",
- "_tautan": [
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/",
- "aksi": "POST",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "GET",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "LETAKKAN",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "HAPUS",
- "tipe": [
- "aplikasi/json"
- ]
- }
- ]
- }
Agar dapat menyimpan catatan, RESTful API harus menyediakan route dengan path ‘/notes’ dengan method POST.
Untuk menyimpan atau menambahkan notes, client akan mengirimkan permintaan ke path dan method tersebut dengan membawa data berformat JSON berikut di dalam request body:
- {
- "judul": "Judul Catatan",
- "tag": ["Tag 1", "Tag 2"],
- "badan": "Konten catatan"
- }
Properti id, createdAt, dan updatedAt harus diolah di sisi server sehingga client tidak perlu mengirimkan data tersebut. RESTful API harus memastikan bahwa properti id selalu unik.
Jika permintaan client berhasil dilakukan, response dari RESTful API harus memiliki status code 201 (created) dan mengembalikan response dalam bentuk JSON dengan format berikut.
- {
- "id": "4dcc2652-064a-41e3-932b-9939d290f408",
- "title": "Catatan pertama saya",
- "body": "Ini adalah contoh catatan saya dalam perjalanan belajar Back-End dengan Django di Dicoding",
- "tag": [
- "Pribadi"
- ],
- "dibuat pada": "2024-11-25T09:05:02.481059Z",
- "updatedAt": "2024-11-25T09:05:02.481106Z",
- "_tautan": [
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/",
- "aksi": "POST",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "GET",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "LETAKKAN",
- "tipe": [
- "aplikasi/json"
- ]
- },
- {
- "rel": "diri sendiri",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "aksi": "HAPUS",
- "tipe": [
- "aplikasi/json"
- ]
- }
- ]
- }
Selain menampilkan data catatan, kita juga menampilkan atribut _links.
Kriteria 2 - RESTful API menyediakan cara untuk menampilkan catatan
Kriteria selanjutnya adalah RESTful API menyediakan cara untuk menampilkan catatan. Kriteria ini mengharuskan RESTful API untuk mengirimkan seluruh atau secara spesifik data notes yang disimpan.
Ketika client melakukan HTTP request pada path ‘/notes’ dengan method ‘GET’, RESTful API harus mengembalikan status code 200 (ok) serta seluruh data notes dalam bentuk array dengan format JSON. Contohnya seperti berikut ini.
- {
- "notes": [
- {
- "id": "468264fa-f0fc-400f-a4ed-de562a21b845",
- "title": "Catatan 1",
- "createdAt": "2024-12-23T23:00:09.686Z",
- "updatedAt": "2024-12-23T23:00:09.686Z",
- "tags": [
- "Tag 1",
- "Tag 2"
- ],
- "body": "Isi dari catatan 1",
- "links": {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/468264fa-f0fc-400f-a4ed-de562a21b845/",
- "action": "GET",
- "types": [
- "application/json"
- ]
- }
- },
- {
- "id": "988264fa-k0fc-800f-f4eb-de562a21b888",
- "title": "Catatan 2",
- "createdAt": "2024-12-23T23:00:09.686Z",
- "updatedAt": "2024-12-23T23:00:09.686Z",
- "tags": [
- "Tag 1",
- "Tag 2"
- ],
- "body": "Isi dari catatan 2",
- "links": {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/988264fa-k0fc-800f-f4eb-de562a21b888/",
- "action": "GET",
- "types": [
- "application/json"
- ]
- }
- }
- ]
- }
Jika tidak ada catatan satu pun pada array, RESTful API bisa mengembalikan data notes dengan nilai array kosong seperti ini.
- {
- "notes": []
- }
Selain itu, client juga bisa melakukan permintaan untuk mendapatkan catatan secara spesifik menggunakan id melalui path ‘/notes/{id}’ dengan method ‘GET’. RESTful API harus mengembalikan status code 200 (ok) serta nilai satu objek catatan dalam format JSON seperti berikut.
- {
- "id": "4dcc2652-064a-41e3-932b-9939d290f408",
- "title": "Catatan pertama saya",
- "body": "Ini adalah contoh catatan saya dalam perjalanan belajar Back-End dengan Django di Dicoding",
- "tags": [
- "Personal"
- ],
- "createdAt": "2024-11-25T09:05:02.481059Z",
- "updatedAt": "2024-11-25T09:05:02.481106Z",
- "_links": [
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/",
- "action": "POST",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "GET",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "PUT",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "DELETE",
- "types": [
- "application/json"
- ]
- }
- ]
- }
Ketika client melampirkan id catatan yang tidak ditemukan, RESTful API harus merespons dengan status code 404 (not found), dan data dalam format JSON seperti berikut ini.
- {
- "detail": "Not found."
- }
Kriteria 3 - RESTful API menyediakan cara untuk mengubah catatan
Kriteria ketiga adalah web server harus menyediakan cara untuk mengubah catatan yang sudah ditambahkan. Perubahan dapat terjadi pada judul, isi, ataupun tag catatan. Ketika client meminta perubahan catatan, ia akan membuat HTTP request ke path ‘/notes/{id}’, menggunakan method ‘PUT’, serta membawa data dalam format JSON pada body request yang merupakan data catatan terbaru.
- {
- "title":"Judul Catatan Revisi",
- "tags":[
- "Tag 1",
- "Tag 2"
- ],
- "body":"Konten catatan"
- }
Jika perubahan data berhasil dilakukan, RESTful API harus menanggapi dengan status code 200 (ok) dan mengembalikan response seperti berikut.
- {
- "id": "468264fa-f0fc-400f-a4ed-de562a21b845",
- "title": "Catatan pertama saya revisi",
- "body": "Ini adalah contoh catatan saya yang sudah diubah",
- "tags": [
- "Personal"
- ],
- "createdAt": "2024-11-25T09:05:02.481059Z",
- "updatedAt": "2024-11-25T09:10:55.573860Z",
- "_links": [
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/",
- "action": "POST",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "GET",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "PUT",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/4dcc2652-064a-41e3-932b-9939d290f408/",
- "action": "DELETE",
- "types": [
- "application/json"
- ]
- }
- ]
- }
Perubahan data catatan harus disimpan ke catatan yang sesuai dengan id yang digunakan pada path parameter. Bila id catatan tidak ditemukan, RESTful API harus merespons dengan status code 404 (not found) dan mengembalikan response seperti berikut.
- {
- "detail": "Not found."
- }
Kriteria 4 - RESTful API dapat menghapus catatan
Kriteria terakhir adalah web server harus bisa menghapus catatan. Untuk menghapus catatan, client akan membuat HTTP request pada path ‘/notes/{id}’ dengan method ‘DELETE’. Ketika permintaan tersebut berhasil, RESTful API harus mengembalikan status code 204 (no content) serta data berformat JSON seperti berikut ini.
Catatan yang dihapus harus sesuai dengan id catatan yang digunakan client pada path parameter. Bila id catatan tidak ditemukan, RESTful API harus mengembalikan response dengan status code 404 dan mengembalikan response seperti berikut.
- {
- "status": "gagal",
- "message": "Catatan gagal dihapus. Id catatan tidak ditemukan"
- }
Itulah kriteria yang perlu dipenuhi oleh kita dalam mengembangkan RESTful API aplikasi catatan.
Setelah mengetahui kriteria proyek dengan jelas dan struktur proyek. Di materi selanjutnya, kita akan mulai latihan membuat proyek!
Latihan: Membuat Proyek Aplikasi Catatan
First things first, membuat proyek aplikasi catatan. Karena sebelumnya kita sudah berlatih membuat proyek dengan Django, sekarang seharusnya Anda sudah lebih mahir. Oleh karena itu, pada latihan kali ini kami tidak akan detail dalam menjelaskan langkah-langkahnya.
- Pertama, buatlah folder baru bernama “notes-app-back-end”.
- Setelah itu, masuk ke dalam folder tersebut.
- Aktifkan virtual environment dengan perintah dibawah ini.
- pipenv shell
- Setelah itu, pasang Django versi 4.2 dengan menggunakan perintah:
- pipenv install django==4.2
- Kemudian, pasang REST Framework dengan menggunakan perintah:
- pipenv install djangorestframework
- Setelah berhasil memasang Django dan REST Framework, selanjutnya membuat proyek Django. Jalankan perintah berikut ini.
- django-admin startproject notes_app_back_end .
- Selanjutnya, untuk membuat Django app, jalankan perintah berikut ini.
- catatan aplikasi mulai django-admin
- Setelah itu, daftarkan Django app dan REST Framework di dalam INSTALLED_APPS.

- Setelah berhasil, akan terbentuk struktur proyek seperti berikut ini.

- Setelah itu, Anda dapat menjalankan server development.

Selamat! Anda sudah berhasil melewati tantangan pertama. Yuk, kita lanjut!
Latihan: Membuat Django Model
Sebelumnya, Andas sudah berhasil membuat proyek aplikasi catatan. Langkah selanjutnya adalah membuat model untuk aplikasi catatan. Yuk, ikuti latihan berikut.
- Pertama, buka berkas models.py yang ada di Django app.
- Selanjutnya, lihat kembali bentuk dari data catatan yang ingin disimpan seperti berikut.
- {
- id: string,
- title: string,
- createdAt: string,
- updatedAt: string,
- tags: array of string,
- body: string,
- },
- Setelah mengetahui struktur dari resources catatan, buatlah model seperti berikut.Karena kita ingin membuat id yang unik dan acak, kita menggunakan UUID. UUID merupakan nilai unik yang berukuran 128-bit untuk mengidentifikasi objek. Untuk atribut tags, kita akan menuliskannya sebagai JSON karena datanya lebih dari satu. Selain itu, atribut
- from django.db import models
- import uuid
- class Note(models.Model):
- id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
- title = models.CharField(max_length=30)
- body = models.TextField()
- tags = models.JSONField()
- createdAt = models.DateTimeField(auto_now_add=True)
- updatedAt = models.DateTimeField(auto_now=True)
createdAtdanupdatedAtmenggunakan fieldDateTimeField(). DateTimeField memiliki argumentauto_now_adduntukcreatedAtagar tanggal diisi secara otomatis ketika data ditambahkan dan argumentauto_nowuntukupdatedAtagar tanggal diisi secara otomatis ketika data diubah.
- Setelah itu, jalankan perintah untuk membuat migrations. Tentunya Anda masih ingat, kan?
- python manage.py makemigrations
- Kemudian, jalankan perintah untuk migrate.Anda akan melihat hasilnya seperti gambar di bawah ini.
- python manage.py migrate
Good job! Anda sudah berhasil membuat model Note untuk kebutuhan aplikasi catatan. Mari kita lanjutkan terlebih dahulu.
Latihan: Mengimplementasi Kriteria 1
Model untuk aplikasi catatan sudah berhasil dibuat. Kini, saatnya untuk menyelesaikan kriteria pertama yaitu menyimpan catatan.
Berdasarkan kriteria yang sudah kita bahas sebelumnya, agar web server dapat menyimpan catatan, kita perlu menyediakan route dengan path /notes dengan method POST. Ayo kita mulai!
- Bukalah berkas views.py yang ada di notes app.
- Selanjutnya, kita akan menuliskan view. Untuk membuat view, kita akan menggunakan teknik class based view karena class based view tidak terlalu tinggi abstraksinya sehingga kita bisa tahu dibalik layar cara kerja RESTful API. Tulislah kode berikut ini.View function yang kita buat bernama NoteList. Di dalamnya terdapat function post untuk menyimpan catatan.
- from rest_framework.response import Response
- from rest_framework.views import APIView
- from rest_framework import status
- from notes.serializers import NoteSerializer
- from .models import Note
- class NoteList(APIView):
- def post(self, request):
- note = NoteSerializer(data=request.data, context={'request': request}) # Pass request context
- if note.is_valid(raise_exception=True):
- note.save()
- return Response(note.data, status=status.HTTP_201_CREATED)
- return Response(note.errors, status=status.HTTP_400_BAD_REQUEST)
- Karena saat ini kita belum memiliki serializer, buatlah berkas baru dengan nama serializers.py di dalam Django app notes.
- Setelah itu, buka berkas serializers.py dan tuliskan kode berikut ini.
- from rest_framework import serializers
- from notes.models import Note
- class NoteSerializer(serializers.HyperlinkedModelSerializer):
- class Meta:
- model = Note
- fields = ['id', 'title', 'body', 'tags', 'createdAt', 'updatedAt']
- Selanjutnya, impor NoteSerializer di dalam views.py secara manual atau Anda dapat memanfaatkan fitur dari PyCharm dengan menghover NoteSerializer dan klik Import “notes.serializers.NoteSerializer’.

- Kemudian, mendaftarkan route di urls.py milik notes app. Caranya adalah membuat berkas baru bernama urls.py di dalam direktori notes.

- Bukalah berkas tersebut dan tuliskan kode berikut.Praktik terbaik di Django adalah menambahkan slash (/) di akhir URL seperti yang ada pada contoh di atas. Hal ini sesuai dengan filosofi dari Django, Anda dapat membacanya lebih lanjut di tautan berikut, Design philosophies. Selain itu, karena kita menggunakan class based, cukup panggil nama class-nya diikuti dengan as_view().
- from django.urls import path
- from . import views
- urlpatterns = [
- path('notes/',views.NoteList.as_view(), name='note-list'),
- ]
- Selanjutnya, mendaftarkan URL milik notes app ke dalam notes_app_back_end projects. Bukalah berkas urls.py milik notes_app_back_end. Tuliskan kode berikut ini.
- from django.contrib import admin
- from django.urls import path, include
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('', include('notes.urls'))
- ]
- Setelah itu, jalankan server development dengan perintah berikut.
- python manage.py runserver
- Saat ini, tugas kita sudah selesai, berikutnya adalah menguji RESTful API untuk menyimpan catatan. Kunjungi halaman http://127.0.0.1:8000/notes/, Anda akan melihat tampilan seperti di bawah ini.

Anda dapat melihat pesan error bahwa method GET tidak diizinkan. Hal ini terjadi karena saat ini kita baru memiliki view function untuk method POST. Tak apa, Anda bisa mengabaikan pesan error tersebut.
- Anda dapat menguji RESTful API untuk menyimpan catatan dengan cara mengisi kolom “content” dengan data berformat JSON seperti berikut.
- {
- "title": "Catatan pertama saya",
- "tags": ["Personal"],
- "body": "Ini adalah contoh catatan saya dalam perjalanan belajar Back-End dengan Django di Dicoding"
- }
Selamat! Anda sudah berhasil menyimpan catatan. Artinya, Anda sudah memenuhi kriteria pertama dari proyek aplikasi catatan. Agar dapat menampilkan catatan yang sudah ditambahkan tersebut, kita akan lanjut ke kriteria yang kedua. Stay tuned, ya!
Latihan: Mengimplementasikan Kriteria 2
Di latihan sebelumnya, kita sudah berhasil untuk menambahkan catatan. Kekurangannya adalah kita tidak dapat melihat catatan yang sudah berhasil ditambahkan. Agar catatan dapat ditampilkan dan kriteria kedua terpenuhi, ayo simak latihan berikut!
- Buka kembali berkas views.py sebelumnya.
- Kemudian, import model Note yang telah dibuat sebelumnya di atas class NoteList.
- from .models import Note
- Setelah itu, di dalam class NoteList, tambahkan function berikut.Sehingga, kode di dalam views.py akan tampak seperti berikut ini.
- def get(self, request):
- notes = Note.objects.all()
- serializer = NoteSerializer(notes, many=True, context={'request': request}) # Pass request context
- return Response({
- "notes": serializer.data
- }, status=status.HTTP_200_OK)
Di dalam function get, kita memanggil model Note dan memanggil fungsi ORM untuk mendapatkan seluruh catatan yaitu Note.objects.all(). Data yang dikembalikan database akan dimasukkan ke dalam serializer untuk mengonversi menjadi data yang digunakan pada response.- class NoteList(APIView):
- def post(self, request):
- note = NoteSerializer(data=request.data, context={'request': request}) # Pass request context
- if note.is_valid(raise_exception=True):
- note.save()
- return Response(note.data, status=status.HTTP_201_CREATED)
- return Response(note.errors, status=status.HTTP_400_BAD_REQUEST)
- def get(self, request):
- notes = Note.objects.all()
- serializer = NoteSerializer(notes, many=True, context={'request': request}) # Pass request context
- return Response({
- "notes": serializer.data
- }, status=status.HTTP_200_OK)
- Selanjutnya, Anda dapat mengunjungi halaman http://127.0.0.1:8000/notes/.
- Anda akan melihat hasil seperti berikut.

Yeay! Kita sudah berhasil menampilkan seluruh data catatan di aplikasi catatan. Namun, ada satu kekurangan yaitu saat ini kita belum bisa menampilkan satu catatan atau melihat detail catatan berdasarkan id catatan. Misalnya mengakses halaman http://localhost:8000/notes/<id>/.
Tampilan di atas adalah hasil ketika Anda mencoba untuk mengakses catatan dengan id tertentu (mendapatkan data catatan spesifik). Saat ini kita belum menangani hal itu sehingga menyebabkan error Page not found. Oleh karena itu, kita akan membuat satu view function lagi agar aplikasi catatan kita dapat menampilkan catatan spesifik berdasarkan id-nya.
- Buka kembali views.py.
- Setelah itu, tambahkan class baru bernama NoteDetail.
- class NoteDetail(APIView):
- Kemudian, di dalamnya tambahkan kode berikut ini.Kode di atas digunakan untuk mendapatkan catatan berdasarkan id catatan (primary key, kunci utama yang bersifat unik). Jika catatan tidak ditemukan, akan dibangkitkan Http 404 (not found). Jangan lupa di views.py import kode berikut
- def get_object(self, pk):
- try:
- return Note.objects.get(pk=pk)
- except Note.DoesNotExist:
- raise Http404
from django.http import Http404untuk raise Http404.
- Selanjutnya, tambahkan function baru berikut ini.Function get akan memanggil function get_object dengan memberikan argument pk (primary key yang didapatkan dari path parameter di URL). Kemudian, memanggil serializer dan mengembalikan response yang berisi serializer data.
- def get(self, request, pk):
- note = self.get_object(pk)
- serializer = NoteSerializer(note)
- return Response(serializer.data)
- Setelah itu, tambahkan URL baru di dalam urls.py notes.Sehingga, hasil lengkapnya seperti berikut.
- path('notes/<uuid:pk>/', views.NoteDetail.as_view())
Class NoteDetail yang telah dibuat sebelumnya akan dipanggil. Kemudian, kita akan menggunakan path parameter untuk mengambil id dari catatan.- from django.urls import path
- from . import views
- urlpatterns = [
- path('notes/',views.NoteList.as_view(), name='note-list'),
- path('notes/<uuid:pk>/', views.NoteDetail.as_view(), name='note-detail'),
- ]
- Anda dapat menguji dengan mengakses URL http://localhost:8000/notes/<id>/. Hasilnya seperti berikut ini.

Saat ini, kita sudah berhasil untuk mendapatkan catatan spesifik. Anda dapat mengubah id yang ada di URL tersebut sesuai dengan id catatan. Jika catatan tidak ditemukan, tampilannya akan seperti berikut ini.
Sudah tidak error “Page not found”, kan? Artinya kita sudah berhasil menangani jika catatan tidak ditemukan.
- Selanjutnya, akses kembali halaman http://127.0.0.1:8000/notes. Anda akan melihat tampilan berikut ini.
Kita akan menambahkan atribut links di dalam objek Note untuk menerapkan prinsip HATEOAS. Anda tentu masih ingat REST Maturity Model, bukan? Jika perlu, Anda dapat membuka modul sebelumnya untuk mengingat kembali konsep tersebut. - Buka kembali serializers.py.
- Setelah itu, tempelkan kode berikut.
- from rest_framework.reverse import reverse
- from notes.models import Note
- class NoteSerializer(serializers.HyperlinkedModelSerializer):
- _links = serializers.SerializerMethodField()
- class Meta:
- model = Note
- fields = ['id', 'title', 'body', 'tags', 'createdAt', 'updatedAt', '_links']
- def get__links(self, obj):
- request = self.context.get('request')
- return [
- {
- "rel": "self",
- "href": reverse('note-list', request=request),
- "action": "POST",
- "types": ["application/json"]
- },
- {
- "rel": "self",
- "href": reverse('note-detail', kwargs={'pk': obj.pk}, request=request),
- "action": "GET",
- "types": ["application/json"]
- }
- ]
_linksmerupakan atribut yang akan kita kembalikan beserta atribut title, body, dan sebagainya._linksmenggunakan serializers. SerializerMethodField(). SerializerMethodField() adalah fields yang mendapatkan nilai dari method yang ada di dalam serializer. Selain itu, perhatikan function berikut.
- def get__links(self, obj):
- request = self.context.get('request')
- return [
- {
- "rel": "self",
- "href": reverse('note-list', request=request),
- "action": "POST",
- "types": ["application/json"]
- },
- {
- "rel": "self",
- "href": reverse('note-detail', kwargs={'pk': obj.pk}, request=request),
- "action": "GET",
- "types": ["application/json"]
- }
- ]
Function di atas digunakan untuk mendapatkan link yang terkait dengan resources saat ini (pada contoh resources-nya adalah note). Berikut rincian dari kode di atas.
- rel: Mengacu kepada hubungan dari link terhadap objek (di sini "self", artinya tautan ke dirinya sendiri yaitu Note).
- href: URL untuk mengakses detail dari objek Note.
- action: HTTP verbs.method yang tersedia atau aksi yang dapat dilakukan terhadap resources.
- types: Content type yang dikembalikan di dalam response.
Jika mengakses kembali halaman http://127.0.0.1:8000/notes. Anda akan mendapatkan response seperti berikut ini:
- {
- "notes": [
- {
- "id": "e4939f0c-abc0-41d9-abcc-542910c59000",
- "title": "Catatan pertama saya",
- "body": "Ini adalah contoh catatan saya dalam perjalanan belajar Back-End dengan Django di Dicoding",
- "tags": [
- "Personal"
- ],
- "createdAt": "2024-11-12T07:58:43.777996Z",
- "updatedAt": "2024-11-12T07:58:43.777996Z",
- "_links": [
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/",
- "action": "POST",
- "types": [
- "application/json"
- ]
- },
- {
- "rel": "self",
- "href": "http://127.0.0.1:8000/notes/0c848a47-3734-4176-bd45-4cd8eccdc16b/",
- "action": "GET",
- "types": [
- "application/json"
- ]
- }
- ]
- }
- ]
- }
Kita sudah berhasil menambahkan atribut links di dalam response. Artinya, kita sudah berhasil menerapkan HATEOAS. Penamaan atribut links dapat Anda sesuaikan, misalnya, menjadi links, links_ dan sebagainya. Kenapa hal ini bisa terjadi? Karena belum ada standar atau convention yang mengatur mengenai penamaan atribut HATEOAS.
Karena seluruh catatan dan yang spesifik sudah berhasil ditampilkan, kriteria kedua dari aplikasi catatan sudah terpenuhi, selamat ya! Selanjutnya, kita akan menuntaskan kriteria berikutnya.
Latihan: Mengimplementasikan Kriteria 3
Menambahkan catatan sudah, menampilkan catatan juga sudah. Kini, kita akan memenuhi kriteria yang ketiga yaitu aplikasi dapat untuk mengubah catatan. Ayo kita mulai!
- Buka kembali views.py.
- Setelah itu, di dalam class NoteDetail tambahkan function put berikut ini.Di dalam function put, kita memanggil function get_object untuk mendapatkan data catatan berdasarkan id-nya. Kemudian, kita menggunakan serializer. Sebelum data disimpan, serializer akan melakukan validasi data menggunakan method is_valid. Jika data request body valid (data yang diinput), serializer akan menyimpannya. Jika tidak valid, serializer akan mengembalikan error dengan status code 400 (bad request).
- def put(self, request, pk):
- catatan = self.get_object(pk)
- serializer = NoteSerializer(note, data=request.data, context={'request': request})
- jika serializer.is_valid():
- serializer.save()
- kembalikan Respons(serializer.data, status=status.HTTP_200_OK)
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
- Kemudian, kita akan mengubah atribut _link. Caranya adalah mengubah function get_links di serializers. Tambahkan kode berikut di dalam array return.Berikut adalah kode lengkapnya function get_links di dalam serializers.
- {
- "rel": "diri sendiri",
- "href": reverse('note-detail', kwargs={'pk': obj.pk}, request=request),
- "aksi": "LETAKKAN",
- "tipe": ["aplikasi/json"]
- }
- def get__links(self, obj):
- permintaan = self.context.get('permintaan')
- kembali [
- {
- "rel": "diri sendiri",
- "href": reverse('note-list', request=request),
- "aksi": "POST",
- "tipe": ["aplikasi/json"]
- },
- {
- "rel": "diri sendiri",
- "href": reverse('note-detail', kwargs={'pk': obj.pk}, request=request),
- "aksi": "GET",
- "tipe": ["aplikasi/json"]
- },
- {
- "rel": "diri sendiri",
- "href": reverse('note-detail', kwargs={'pk': obj.pk}, request=request),
- "aksi": "LETAKKAN",
- "tipe": ["aplikasi/json"]
- }
- Selanjutnya, kunjungi halaman http://localhost:8000/notes/<id>/.
- Anda dapat mengujinya dengan mengirimkan data berikut ini di dalam Content.
- {
- "title": "Catatan pertama saya revisi",
- "tag": ["Pribadi"],
- "body": "Ini adalah contoh catatan saya yang sudah diubah"
- }
Cool! Anda sudah berhasil mengubah catatan yang sudah ada. Kriteria ketiga pun sudah terpenuhi. Masih semangat, kan? Masih ada satu kriteria lagi.
Latihan: Mengimplementasikan Kriteria 4
Akhirnya, kita sudah sampai di kriteria terakhir yaitu aplikasi mampu menghapus catatan. Bagaimana cara untuk memenuhi kriteria tersebut? Simak latihan berikut ini.
- Buka kembali berkas views.py.
- Kemudian, tambahkan function baru di dalam class NoteDetail.Function tersebut bernama delete. Di dalamnya terdapat note yang memanggil function get_object untuk mendapatkan catatan spesifik. Kemudian, kita memanggil method delete milik ORM dan mengembalikan response dengan status code 204 (no content).
- def delete(self, request, pk):
- note = self.get_object(pk)
- note.delete()
- return Response(status=status.HTTP_204_NO_CONTENT)
- Akses kembali halaman http://localhost:8000/notes/<id>/. Anda akan melihat tombol DELETE berwarna merah di bagian atas.
Tombol DELETE tersebut dihasilkan secara otomatis oleh API view.
- Setelah itu, klik tombol DELETE.
- Anda akan melihat pop up konfirmasi seperti berikut.

- Klik Delete.
- Jika berhasil, Anda akan mendapatkan response seperti berikut.
Perhatikan status code yang diberikan. Status code yang didapatkan adalah 204 (no content). Jika Anda mencoba untuk mengakses http://127.0.0.1:8000/notes/<id>/, akan mendapatkan tampilan not found berikut.
Yeay! Anda sudah berhasil untuk menghapus catatan dengan id spesifik. Saat ini, kita sudah memenuhi kriteria terakhir yaitu aplikasi mampu untuk menghapus catatan.
Sejauh ini, Anda sudah berhasil menerapkan seluruh kriteria proyek aplikasi catatan yang telah kita definisikan di awal modul ini. Kami bangga akan ketekunan dan kegigihan Anda dalam mengikuti latihan membuat RESTful API dengan studi kasus aplikasi catatan. Aplikasi catatan yang telah dikembangkan sangat menarik, sayang apabila aplikasi tersebut hanya digunakan secara lokal (di komputer Anda). Tentunya, Anda ingin aplikasi catatan dapat diakses di mana saja. Untuk melakukan hal itu, kita perlu melakukan proses deployment atau merilis aplikasi ke server yang dapat diakses secara publik.
Penasaran bagaimana? Ayo kita meluncur ke modul “Deploy Web Service ke Google Cloud”.
Rangkuman Django REST Framework
Selamat! Anda sudah berada di penghujung modul Django REST Framework. Mari kita uraikan materi yang sudah Anda pelajari untuk menyegarkan ingatan Anda tentang materi tersebut.
API View Decorator
API decorator adalah decorator yang akan membaca HTTP method yang harus diresponse oleh view function. Secara bawaan, API decorator dapat membaca HTTP method GET. Jika ingin menggunakan HTTP method lainnya, Anda harus menuliskannya secara eksplisit. Berikut contohnya:
- @api_view(['GET', 'POST', 'PUT', 'DELETE'])
Serializers
Serializers merupakan fitur populer yang ada di REST Framework. Serializers adalah cara untuk mengonversi data yang kompleks seperti model menjadi data yang bertipe data native Python. Ketika data tersebut sudah menjadi tipe data native Python, akan lebih mudah untuk mengubahnya menjadi JSON atau XML.
Deserializers
Deserializer adalah kebalikan dari serializer dan deserializer terjadi saat client mengirimkan data melalui HTTP POST. Deserializer akan merutekan data tersebut ke model yang ada. Deserializer berfungsi untuk mengonversi data dari format JSON ke model.
Function Based View
Function based view (FBV) adalah cara mendefinisikan view di Django menggunakan fungsi Python biasa. Function based view menggunakan function Python biasa untuk menerima request dan mengembalikan response. Function based view menggunakan class Request milik REST Framework untuk menerima HTTP request (bukan class HttpRequest milik Django). Untuk mengembalikan response ke client, function based view menggunakan class Response milik REST Framework (bukan HttpResponse milik Django).
Class Based View
Class based view adalah view yang mewarisi (inheritance) class APIView milik REST Framework. Penggunaan APIView hampir sama seperti view biasanya, HTTP request yang masuk akan diterima dan diproses hingga memberikan response. Class based view juga menggunakan class Request dan Response, sama seperti Function based view.
Kelebihan dari class based view yaitu mengurangi kode yang ditulis sehingga duplikasi kode berkurang. Selain itu, kita dapat menulis function yang berbeda di dalamnya sesuai dengan HTTP method seperti POST, GET, DELETE, dan sebagainya.
ViewSet
ViewSet adalah jenis view function yang berbasis class. Perbedaannya dengan class based view adalah ViewSet tidak menyediakan fungsi seperti .get(), .post() dan sebagainya. Sebagai gantinya, ViewSet menyediakan fungsi seperti create .list(), .create(). Di dalam ViewSet memungkinkan untuk menggabungkan logika yang ada di view dalam satu class. Di dalam ViewSet memungkinkan untuk menuliskan logika CRUD (Create, Read, Update, Delete).
Routing
Routing sendiri adalah teknik yang digunakan untuk menghubungkan URL dengan tampilan halaman web atau endpoint RESTful API. Di modul ini, kita akan bahas lebih lanjut tentang routing di Django.
Ketika menggunakan ViewSet, disarankan untuk menggunakan router agar tidak perlu menulis URL secara eksplisit satu per satu.
Django Model
Model adalah objects yang menjadi sumber informasi tentang data yang digunakan di aplikasi. Di dalam model terdapat informasi yang penting seperti atribut yang dimiliki oleh data. Biasanya, setiap model akan ditujukan ke satu tabel yang ada di Database. Setiap atribut yang ada di model, merepresentasikan atribut yang ada di Database.
Misalnya, membuat model untuk sebuah buku. Buku memiliki atribut judul, tahun terbit dan penulis. Berikut contoh model buku.
- from django.db import models
- class Book(models.Model):
- title = models.CharField(max_length=30)
- publish_date = models.IntegerField()
- author = models.CharField(max_length=50)
- Get link
- X
- Other Apps










Comments
Post a Comment