Rehberler Uzun Okuma api

Django ile API nasil insa edilir?

Serializer validasyonu, ViewSet CRUD ve router tabanli URL yapisi.

1 Şubat 2026 21 dk okuma
Paylaş
X in

Giris

Django REST Framework (DRF), Django uzerinde JSON/XML API'ler insa etmek icin endustri standardi bir arac setidir. Serializer katmani veri donusumu ve validasyonu, View/ViewSet katmani HTTP semantigini, permission ve throttle katmanlari guvenligi yonetir.

Bu yazida temel Serializer'dan ModelViewSet'e kadar ilerleyerek tam bir blog API'si ornegi kuracagiz. Nested serializer, custom validation ve pagination gibi gercek dunya ihtiyaclarini ele alacagiz.

Serializer Temelleri

Serializer, Python nesnelerini JSON'a ve tersine cevirir. is_valid() cagrisi validation calistirir; validated_data temiz girdiyi icerir. read_only ve write_only alanlar API sozlesmesini netlestirir.

  • serializer.data: serialize edilmis cikti
  • serializer.save(): create/update hook'lari
  • to_representation() ile custom cikti formati
from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    body = serializers.CharField(max_length=1000)

    def validate_body(self, value):
        if len(value.strip()) < 10:
            raise serializers.ValidationError('Yorum en az 10 karakter olmali.')
        return value

ModelSerializer ve Iliskiler

ModelSerializer, Model meta verisinden otomatik alan uretir. PrimaryKeyRelatedField ve nested serializer ile ForeignKey/ManyToMany iliskileri expose edilir. depth parametresi hizli prototipleme icin kullanilir ancak uretimde kontrol kaybina yol acar.

class PostSerializer(serializers.ModelSerializer):
    author_name = serializers.CharField(source='author.username', read_only=True)
    tags = serializers.SlugRelatedField(
        many=True, slug_field='name', queryset=Tag.objects.all()
    )

    class Meta:
        model = Post
        fields = ['id', 'title', 'slug', 'body', 'author_name', 'tags']
        read_only_fields = ['id', 'slug']

APIView ve Generic View

APIView her HTTP metodu icin ayri handler saglar. Generic view'lar ListCreateAPIView gibi hazir kaliplar sunar. Performans icin queryset uzerinde select_related kullanmayi unutmayin.

from rest_framework import generics, permissions

class PostListCreateAPIView(generics.ListCreateAPIView):
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def get_queryset(self):
        return Post.objects.select_related('author').prefetch_related('tags')
Her endpoint icin queryset'i view'da tanimlayin; serializer veri sekline, view erisim kurallarina sahip olsun.

ViewSet ve Router

ViewSet, CRUD aksiyonlarini tek sinifta toplar: list, retrieve, create, update, destroy. DefaultRouter otomatik URL uretir. @action decorator ile ozel endpoint eklenebilir.

from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.select_related('author')
    serializer_class = PostSerializer
    lookup_field = 'slug'

    @action(detail=True, methods=['post'])
    def publish(self, request, slug=None):
        post = self.get_object()
        post.publish()
        return Response({'status': 'published'})

Permission, Pagination ve Filtering

IsAuthenticated, DjangoModelPermissions ve custom permission siniflari erisim kontrolu saglar. PageNumberPagination ile sayfalama standartlastirilir. django-filter entegrasyonu ile query param filtreleme eklenir.

  • permission_classes view veya ViewSet seviyesinde
  • throttle_classes rate limiting icin
  • renderer_classes JSON disinda format destegi
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 20,
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
    ],
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
    ],
}

Hata Yonetimi ve Test

DRF tutarli hata formati doner: {'field': ['mesaj']}. APIClient ile entegrasyon testleri yazilir. force_authenticate ile auth durumu simule edilir.

  1. Serializer unit test: is_valid() ve validate_* metodlari
  2. APITestCase ile HTTP status ve payload
  3. Factory pattern ile test verisi
from rest_framework.test import APITestCase

class PostAPITest(APITestCase):
    def test_create_requires_auth(self):
        response = self.client.post('/api/posts/', {'title': 'Test'})
        self.assertEqual(response.status_code, 401)

Sonuc

DRF ile API gelistirmek Django'nun ORM ve auth altyapisini bozmadan olceklenebilir servisler uretmenizi saglar. ViewSet + Router kombinasyonu CRUD projelerinde hiz kazandirir; karmasik is akislari icin APIView veya custom action tercih edin.

  • Nested serializer'da N+1'e dikkat (prefetch_related)
  • Versiyonlama icin namespace veya URL prefix
  • OpenAPI schema: drf-spectacular kullanin