Source profileQuality 80/100

affaan-m/ECC/docs/tr/skills/api-design/SKILL.md

api-design

REST API tasarım kalıpları; kaynak isimlendirme, durum kodları, sayfalama, filtreleme, hata yanıtları, versiyonlama ve üretim API'leri için hız sınırlama içerir.

Source repository stars
234,327
Declared platforms
1
Static risk flags
0
Last source update
2026-07-27
Source checked
2026-07-28

Decision brief

What it does—and where it fits

Tutarlı, geliştirici dostu REST API'leri tasarlamak için konvansiyonlar ve en iyi uygulamalar.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorDeclaredSource recordInstall path and trigger
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/api-design"
    Safe inspection promptEditorial

    Inspect the Agent Skill "api-design" from https://github.com/affaan-m/ECC/blob/4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38/docs/tr/skills/api-design/SKILL.md at commit 4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Ne Zaman Aktifleştirmeli

      Yeni API endpoint'leri tasarlarken

      Yeni API endpoint'leri tasarlarkenMevcut API sözleşmelerini incelerkenSayfalama, filtreleme veya sıralama eklerken
    2. 02

      Kaynak Tasarımı

      Review the “Kaynak Tasarımı” section in the pinned source before continuing.

      Review and apply the “Kaynak Tasarımı” source section.
    3. 03

      URL Yapısı

      Review the “URL Yapısı” section in the pinned source before continuing.

      Review and apply the “URL Yapısı” source section.
    4. 04

      Kaynaklar isim, çoğul, küçük harf, kebab-case

      GET /api/v1/users GET /api/v1/users/:id POST /api/v1/users PUT /api/v1/users/:id PATCH /api/v1/users/:id DELETE /api/v1/users/:id

      GET /api/v1/users GET /api/v1/users/:id POST /api/v1/users PUT /api/v1/users/:id PATCH /api/v1/users/:id DELETE /api/v1/users/:id
    5. 05

      İlişkiler için alt kaynaklar

      GET /api/v1/users/:id/orders POST /api/v1/users/:id/orders

      GET /api/v1/users/:id/orders POST /api/v1/users/:id/orders

    Permission review

    Static risk signals and limitations

    No configured static risk pattern was detected

    This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score80/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars234,327SourceRepository attention, not individual Skill quality
    Compatibility1 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    affaan-m/ECC
    Skill path
    docs/tr/skills/api-design/SKILL.md
    Commit
    4e973d3eaf92d97f8d2e2d8abb39d8bdc8711b38
    License
    MIT
    Collected
    2026-07-28
    Default branch
    main
    View the original SKILL.md

    API Tasarım Kalıpları

    Tutarlı, geliştirici dostu REST API'leri tasarlamak için konvansiyonlar ve en iyi uygulamalar.

    Ne Zaman Aktifleştirmeli

    • Yeni API endpoint'leri tasarlarken
    • Mevcut API sözleşmelerini incelerken
    • Sayfalama, filtreleme veya sıralama eklerken
    • API'ler için hata işleme uygularken
    • API versiyonlama stratejisi planlarken
    • Halka açık veya iş ortağı odaklı API'ler oluştururken

    Kaynak Tasarımı

    URL Yapısı

    # Kaynaklar isim, çoğul, küçük harf, kebab-case
    GET    /api/v1/users
    GET    /api/v1/users/:id
    POST   /api/v1/users
    PUT    /api/v1/users/:id
    PATCH  /api/v1/users/:id
    DELETE /api/v1/users/:id
    
    # İlişkiler için alt kaynaklar
    GET    /api/v1/users/:id/orders
    POST   /api/v1/users/:id/orders
    
    # CRUD'a uymayan aksiyonlar (fiilleri dikkatli kullanın)
    POST   /api/v1/orders/:id/cancel
    POST   /api/v1/auth/login
    POST   /api/v1/auth/refresh
    

    İsimlendirme Kuralları

    # İYİ
    /api/v1/team-members          # çok sözcüklü kaynaklar için kebab-case
    /api/v1/orders?status=active  # filtreleme için query parametreleri
    /api/v1/users/123/orders      # sahiplik için iç içe kaynaklar
    
    # KÖTÜ
    /api/v1/getUsers              # URL'de fiil
    /api/v1/user                  # tekil (çoğul kullanın)
    /api/v1/team_members          # URL'lerde snake_case
    /api/v1/users/123/getOrders   # iç içe kaynaklarda fiil
    

    HTTP Metodları ve Durum Kodları

    Metod Semantiği

    MetodIdempotentGüvenliKullanım Amacı
    GETEvetEvetKaynakları getir
    POSTHayırHayırKaynak oluştur, aksiyonları tetikle
    PUTEvetHayırKaynağın tam değişimi
    PATCHHayır*HayırKaynağın kısmi güncellemesi
    DELETEEvetHayırKaynağı kaldır

    *PATCH uygun implementasyonla idempotent yapılabilir

    Durum Kodu Referansı

    # Başarı
    200 OK                    — GET, PUT, PATCH (yanıt body'si ile)
    201 Created               — POST (Location header ekleyin)
    204 No Content            — DELETE, PUT (yanıt body'si yok)
    
    # İstemci Hataları
    400 Bad Request           — Validasyon hatası, hatalı JSON
    401 Unauthorized          — Eksik veya geçersiz kimlik doğrulama
    403 Forbidden             — Kimlik doğrulandı ama yetkilendirilmedi
    404 Not Found             — Kaynak mevcut değil
    409 Conflict              — Tekrar kayıt, durum çakışması
    422 Unprocessable Entity  — Semantik olarak geçersiz (geçerli JSON, kötü veri)
    429 Too Many Requests     — Hız limiti aşıldı
    
    # Sunucu Hataları
    500 Internal Server Error — Beklenmeyen hata (detayları açığa çıkarmayın)
    502 Bad Gateway           — Upstream servis başarısız
    503 Service Unavailable   — Geçici aşırı yük, Retry-After ekleyin
    

    Yaygın Hatalar

    # KÖTÜ: Her şey için 200
    { "status": 200, "success": false, "error": "Not found" }
    
    # İYİ: HTTP durum kodlarını semantik olarak kullanın
    HTTP/1.1 404 Not Found
    { "error": { "code": "not_found", "message": "User not found" } }
    
    # KÖTÜ: Validasyon hataları için 500
    # İYİ: Alan düzeyinde detaylarla 400 veya 422
    
    # KÖTÜ: Oluşturulan kaynaklar için 200
    # İYİ: Location header ile 201
    HTTP/1.1 201 Created
    Location: /api/v1/users/abc-123
    

    Yanıt Formatı

    Başarı Yanıtı

    {
      "data": {
        "id": "abc-123",
        "email": "alice@example.com",
        "name": "Alice",
        "created_at": "2025-01-15T10:30:00Z"
      }
    }
    

    Koleksiyon Yanıtı (Sayfalama ile)

    {
      "data": [
        { "id": "abc-123", "name": "Alice" },
        { "id": "def-456", "name": "Bob" }
      ],
      "meta": {
        "total": 142,
        "page": 1,
        "per_page": 20,
        "total_pages": 8
      },
      "links": {
        "self": "/api/v1/users?page=1&per_page=20",
        "next": "/api/v1/users?page=2&per_page=20",
        "last": "/api/v1/users?page=8&per_page=20"
      }
    }
    

    Hata Yanıtı

    {
      "error": {
        "code": "validation_error",
        "message": "Request validation failed",
        "details": [
          {
            "field": "email",
            "message": "Must be a valid email address",
            "code": "invalid_format"
          },
          {
            "field": "age",
            "message": "Must be between 0 and 150",
            "code": "out_of_range"
          }
        ]
      }
    }
    

    Yanıt Zarfı Varyantları

    // Seçenek A: Data sarmalayıcılı zarf (halka açık API'ler için önerilir)
    interface ApiResponse<T> {
      data: T;
      meta?: PaginationMeta;
      links?: PaginationLinks;
    }
    
    interface ApiError {
      error: {
        code: string;
        message: string;
        details?: FieldError[];
      };
    }
    
    // Seçenek B: Düz yanıt (daha basit, dahili API'ler için yaygın)
    // Başarı: kaynağı doğrudan döndür
    // Hata: hata nesnesini döndür
    // HTTP durum koduyla ayırt et
    

    Sayfalama

    Offset-Tabanlı (Basit)

    GET /api/v1/users?page=2&per_page=20
    
    # Implementasyon
    SELECT * FROM users
    ORDER BY created_at DESC
    LIMIT 20 OFFSET 20;
    

    Artıları: Uygulaması kolay, "N sayfasına git" destekler Eksileri: Büyük offset'lerde yavaş (OFFSET 100000), eş zamanlı eklemelerde tutarsız

    Cursor-Tabanlı (Ölçeklenebilir)

    GET /api/v1/users?cursor=eyJpZCI6MTIzfQ&limit=20
    
    # Implementasyon
    SELECT * FROM users
    WHERE id > :cursor_id
    ORDER BY id ASC
    LIMIT 21;  -- has_next belirlemek için bir fazla getir
    
    {
      "data": [...],
      "meta": {
        "has_next": true,
        "next_cursor": "eyJpZCI6MTQzfQ"
      }
    }
    

    Artıları: Pozisyondan bağımsız tutarlı performans, eş zamanlı eklemelerde kararlı Eksileri: Rastgele sayfaya atlayamaz, cursor opak

    Hangisi Ne Zaman Kullanılmalı

    Kullanım SenaryosuSayfalama Tipi
    Admin panelleri, küçük veri setleri (<10K)Offset
    Sonsuz kaydırma, akışlar, büyük veri setleriCursor
    Halka açık API'lerCursor (varsayılan) ile offset (opsiyonel)
    Arama sonuçlarıOffset (kullanıcılar sayfa numarası bekler)

    Filtreleme, Sıralama ve Arama

    Filtreleme

    # Basit eşitlik
    GET /api/v1/orders?status=active&customer_id=abc-123
    
    # Karşılaştırma operatörleri (köşeli parantez notasyonu kullanın)
    GET /api/v1/products?price[gte]=10&price[lte]=100
    GET /api/v1/orders?created_at[after]=2025-01-01
    
    # Çoklu değerler (virgülle ayrılmış)
    GET /api/v1/products?category=electronics,clothing
    
    # İç içe alanlar (nokta notasyonu)
    GET /api/v1/orders?customer.country=US
    

    Sıralama

    # Tek alan (azalan için - öneki)
    GET /api/v1/products?sort=-created_at
    
    # Çoklu alanlar (virgülle ayrılmış)
    GET /api/v1/products?sort=-featured,price,-created_at
    

    Tam Metin Arama

    # Arama query parametresi
    GET /api/v1/products?q=wireless+headphones
    
    # Alana özel arama
    GET /api/v1/users?email=alice
    

    Seyrek Fieldset'ler

    # Sadece belirtilen alanları döndür (payload'ı azaltır)
    GET /api/v1/users?fields=id,name,email
    GET /api/v1/orders?fields=id,total,status&include=customer.name
    

    Kimlik Doğrulama ve Yetkilendirme

    Token-Tabanlı Auth

    # Authorization header'da Bearer token
    GET /api/v1/users
    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
    
    # API key (sunucudan sunucuya)
    GET /api/v1/data
    X-API-Key: sk_live_abc123
    

    Yetkilendirme Kalıpları

    // Kaynak seviyesi: sahipliği kontrol et
    app.get("/api/v1/orders/:id", async (req, res) => {
      const order = await Order.findById(req.params.id);
      if (!order) return res.status(404).json({ error: { code: "not_found" } });
      if (order.userId !== req.user.id) return res.status(403).json({ error: { code: "forbidden" } });
      return res.json({ data: order });
    });
    
    // Rol-tabanlı: yetkileri kontrol et
    app.delete("/api/v1/users/:id", requireRole("admin"), async (req, res) => {
      await User.delete(req.params.id);
      return res.status(204).send();
    });
    

    Hız Sınırlama

    Header'lar

    HTTP/1.1 200 OK
    X-RateLimit-Limit: 100
    X-RateLimit-Remaining: 95
    X-RateLimit-Reset: 1640000000
    
    # Aşıldığında
    HTTP/1.1 429 Too Many Requests
    Retry-After: 60
    {
      "error": {
        "code": "rate_limit_exceeded",
        "message": "Rate limit exceeded. Try again in 60 seconds."
      }
    }
    

    Hız Limit Katmanları

    KatmanLimitPencereKullanım Senaryosu
    Anonim30/dkIP BaşınaHalka açık endpoint'ler
    Kimlik Doğrulanmış100/dkKullanıcı BaşınaStandart API erişimi
    Premium1000/dkAPI key BaşınaÜcretli API planları
    Dahili10000/dkServis BaşınaServisten servise

    Versiyonlama

    URL Yolu Versiyonlama (Önerilen)

    /api/v1/users
    /api/v2/users
    

    Artıları: Açık, yönlendirmesi kolay, cache'lenebilir Eksileri: Versiyonlar arası URL değişir

    Header Versiyonlama

    GET /api/users
    Accept: application/vnd.myapp.v2+json
    

    Artıları: Temiz URL'ler Eksileri: Test etmesi zor, unutulması kolay

    Versiyonlama Stratejisi

    1. /api/v1/ ile başlayın — ihtiyaç duyana kadar versiyonlamayın
    2. En fazla 2 aktif versiyon koruyun (mevcut + önceki)
    3. Kullanımdan kaldırma zaman çizelgesi:
       - Kullanımdan kaldırmayı duyurun (halka açık API'ler için 6 ay önceden)
       - Sunset header ekleyin: Sunset: Sat, 01 Jan 2026 00:00:00 GMT
       - Sunset tarihinden sonra 410 Gone döndürün
    4. Breaking olmayan değişiklikler yeni versiyon gerektirmez:
       - Yanıtlara yeni alanlar eklemek
       - Yeni opsiyonel query parametreleri eklemek
       - Yeni endpoint'ler eklemek
    5. Breaking değişiklikler yeni versiyon gerektirir:
       - Alanları kaldırmak veya yeniden adlandırmak
       - Alan tiplerini değiştirmek
       - URL yapısını değiştirmek
       - Kimlik doğrulama metodunu değiştirmek
    

    Implementasyon Kalıpları

    TypeScript (Next.js API Route)

    import { z } from "zod";
    import { NextRequest, NextResponse } from "next/server";
    
    const createUserSchema = z.object({
      email: z.string().email(),
      name: z.string().min(1).max(100),
    });
    
    export async function POST(req: NextRequest) {
      const body = await req.json();
      const parsed = createUserSchema.safeParse(body);
    
      if (!parsed.success) {
        return NextResponse.json({
          error: {
            code: "validation_error",
            message: "Request validation failed",
            details: parsed.error.issues.map(i => ({
              field: i.path.join("."),
              message: i.message,
              code: i.code,
            })),
          },
        }, { status: 422 });
      }
    
      const user = await createUser(parsed.data);
    
      return NextResponse.json(
        { data: user },
        {
          status: 201,
          headers: { Location: `/api/v1/users/${user.id}` },
        },
      );
    }
    

    Python (Django REST Framework)

    from rest_framework import serializers, viewsets, status
    from rest_framework.response import Response
    
    class CreateUserSerializer(serializers.Serializer):
        email = serializers.EmailField()
        name = serializers.CharField(max_length=100)
    
    class UserSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ["id", "email", "name", "created_at"]
    
    class UserViewSet(viewsets.ModelViewSet):
        serializer_class = UserSerializer
        permission_classes = [IsAuthenticated]
    
        def get_serializer_class(self):
            if self.action == "create":
                return CreateUserSerializer
            return UserSerializer
    
        def create(self, request):
            serializer = CreateUserSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            user = UserService.create(**serializer.validated_data)
            return Response(
                {"data": UserSerializer(user).data},
                status=status.HTTP_201_CREATED,
                headers={"Location": f"/api/v1/users/{user.id}"},
            )
    

    Go (net/http)

    func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
        var req CreateUserRequest
        if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
            writeError(w, http.StatusBadRequest, "invalid_json", "Invalid request body")
            return
        }
    
        if err := req.Validate(); err != nil {
            writeError(w, http.StatusUnprocessableEntity, "validation_error", err.Error())
            return
        }
    
        user, err := h.service.Create(r.Context(), req)
        if err != nil {
            switch {
            case errors.Is(err, domain.ErrEmailTaken):
                writeError(w, http.StatusConflict, "email_taken", "Email already registered")
            default:
                writeError(w, http.StatusInternalServerError, "internal_error", "Internal error")
            }
            return
        }
    
        w.Header().Set("Location", fmt.Sprintf("/api/v1/users/%s", user.ID))
        writeJSON(w, http.StatusCreated, map[string]any{"data": user})
    }
    

    API Tasarım Kontrol Listesi

    Yeni bir endpoint yayınlamadan önce:

    • Kaynak URL isimlendirme konvansiyonlarını takip ediyor (çoğul, kebab-case, fiil yok)
    • Doğru HTTP metodu kullanılıyor (okumalar için GET, oluşturmalar için POST, vb.)
    • Uygun durum kodları döndürülüyor (her şey için 200 değil)
    • Girdi şema ile validasyona tabi tutuluyor (Zod, Pydantic, Bean Validation)
    • Hata yanıtları kodlar ve mesajlarla standart formatı takip ediyor
    • Liste endpoint'leri için sayfalama uygulanmış (cursor veya offset)
    • Kimlik doğrulama gerekli (veya açıkça halka açık işaretlenmiş)
    • Yetkilendirme kontrol ediliyor (kullanıcı sadece kendi kaynaklarına erişebilir)
    • Hız sınırlama yapılandırılmış
    • Yanıt dahili detayları sızdırmıyor (stack trace'ler, SQL hataları)
    • Mevcut endpoint'lerle tutarlı isimlendirme (camelCase vs snake_case)
    • Dokümante edilmiş (OpenAPI/Swagger spec güncellenmiş)

    Alternatives

    Compare before choosing