Giriş.
Rest Framework ile geliştirme yaparken aynı endpoint üzerine gelen farklı formatlardaki istekleri işleyebilir yine aynı endpoint üzerinden farklı formatlara sahip cevaplar dönebilirsiniz.
Desteklenen cevap formatları renderer_classes, desteklenen istek formatları ise parser_classes üzerinde belirtilir.
Modern API’lar geliştirirken en çok kullanılan veri alış-veriş formatı JSON olsada bazı durumlarda farklı formatlara ihtiyaç duyabiliriz. Örneğin API’nızı kullanacak olan nispeten eski istemciler varsa sizden XML formatında veri alış-verişini desteklemeniz istenebilir.
Bugün XML parsing ve rendering işlemlerinin DRF ile nasıl yapılabileceğine göz atacağız.
Kurulum ve kullanım.
Eski sürümlerde XML rendering ve parsing için DRF yerleşik bir çözüm barındırıyor olsa da daha sonraki sürümlerde bu özellik 3rd party olarak RestFramework XML paketi altında sunulmakta ve geliştirilmekte.
O yüzden ilk olarak geliştirme ortamımıza bu paketi kuralım.
Bu paket şu anda Python 3.5+ ve Django 2.2+ sürümlerine destek vermekte.
$ pip install djangorestframework-xml
Örnek bir kullanım için, varsayılan kullanıcı modelini kullanacağız.
Kullanıcıları oluştururken ve listelerken kullanılacak olan serializer ve viewı tanımlayalım.
# your_app/serializers.py from django.contrib.auth import get_user_model from rest_framework import serializers User = get_user_model() class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = "__all__" extra_kwargs = {"password": {"write_only": True}}
# your_app/views.py from django.contrib.auth import get_user_model from rest_framework.generics import ListCreateAPIView from rest_framework.parsers import JSONParser from rest_framework.renderers import JSONRenderer from rest_framework_xml.parsers import XMLParser from rest_framework_xml.renderers import XMLRenderer from users.serializers import UserSerializer User = get_user_model() class UserListView(ListCreateAPIView): serializer_class = UserSerializer queryset = User.objects.all() renderer_classes = [JSONRenderer, XMLRenderer] parser_classes = [JSONParser, XMLParser]
DRF plugabble bir mimariye sahiptir. Dolayısıyla restframework-xml paketi altından import ettiğimiz XMLParser ve XMLRenderer sınıflarını spesifik bir view üzerine kayıt edebiliriz.
DRF gelen isteğin, Accept headerına göre yada query param format değerine göre, renderer_classes üzerinde tanımlı olan formatlardan biri ile cevap dönmeye çalışacaktır.
Listelemeyi test edelim.
$ http --body "localhost:9001/api/users/?format=xml" <?xml version="1.0" encoding="utf-8"?> <root> <list-item> <id>1</id> <last_login/> <is_superuser>True</is_superuser> <username>egehan</username> <first_name/> <last_name/> <email>egehan.gundogdu@gmail.com</email> <is_staff>True</is_staff> <is_active>True</is_active> <date_joined>2022-02-20T12:07:21.009928Z</date_joined> <groups/> <user_permissions/> </list-item> </root>
XML formatta bir body ile kullanıcı kayıt edelim.
$ printf '<?xml version="1.0" encoding="utf-8"?> <root> <username>egehan_xml</username> <first_name>egehan</first_name> <last_name>xml</last_name> <email>egehan.gundogdu@xml.com</email> <password>secure_password</password> </root>'| http --follow --timeout 3600 POST 'http://localhost:9001/api/users/' \ Accept:'application/xml' \ Content-Type:'application/xml' HTTP/1.1 201 Created Allow: GET, POST, HEAD, OPTIONS Content-Length: 409 Content-Type: application/xml; charset=utf-8 Date: Sun, 20 Feb 2022 13:33:37 GMT Referrer-Policy: same-origin Server: WSGIServer/0.2 CPython/3.9.6 Vary: Accept, Cookie X-Content-Type-Options: nosniff X-Frame-Options: DENY <?xml version="1.0" encoding="utf-8"?> <root> <id>10</id> <last_login/> <is_superuser>False</is_superuser> <username>egehan_xml</username> <first_name>egehan</first_name> <last_name>xml</last_name> <email>egehan.gundogdu@xml.com</email> <is_staff>False</is_staff> <is_active>True</is_active> <date_joined>2022-02-20T13:33:37.428488Z</date_joined> <groups/> <user_permissions/> </root>
Güzel! Artık XML formatta gelen bir istek gövdesini parse edebiliyor ve cevabı yine aynı formatta dönebiliyoruz.
Fakat dikkat ettiyseniz, listeleme sırasında XML deki en dıştaki elementin tagi root, serialize edilen her objenin kapsayıcı tagi ise list-item.
Eğer burada da bir özelleştirmeye ihtiyacınız varsa custom bir renderer sınıfı yazabilir ve viewınıza kayıt edebilirsiniz.
from rest_framework_xml.renderers import XMLRenderer class CustomUserXMLRenderer(XMLRenderer): item_tag_name = "user" root_tag_name = "user-list"
$ http --body "http://localhost:9001/api/users/?format=xml" <?xml version="1.0" encoding="utf-8"?> <user-list> <user> <id>1</id> <last_login/> <is_superuser>True</is_superuser> <username>egehan</username> <first_name/> <last_name/> <email>egehan.gundogdu@gmail.com</email> <is_staff>True</is_staff> <is_active>True</is_active> <date_joined>2022-02-20T12:07:21.009928Z</date_joined> <groups/> <user_permissions/> </user> </user-list>
Son olarak eğer tüm endpointlerinizin, XML render ve parse edebilme yeteneğine sahip olmasını istiyorsanız doğrudan DRF global settings olarak belirtebilirsiniz.
# your_project/settings.py REST_FRAMEWORK = { "DEFAULT_PARSER_CLASSES" : [ "rest_framework.parsers.JSONParser", "rest_framework_xml.parsers.XMLParser" ], "DEFAULT_RENDERER_CLASSES" : [ "rest_framework.renderers.JSONRenderer", "rest_framework_xml.renderers.XMLRenderer", ] }
DRF (ve tabiki pure Django) ihtiyaçlar doğrultusunda kolay ve hızlıca genişletilebilen, topluluğu oturmuş çok kuvvetli bir web geliştirme aracı. Daha önce Python ve Django ile geliştirme yapmamış iseniz bir şans vermeniz web geliştirmeye bakış açınızı fazlasıyla değiştirebilir 🙂
Bu blogta daha fazla DRF hakkında okumak isterseniz link burada.
RestFramework-XML kütüphanesi dökümantasyonu.
Django Rest Framework dökümantasyon linki ise burada.
Keyifli ve sağlıklı günler!
İlk Yorumu Siz Yapın