Makale

API Tasarımı En İyi Uygulamaları

API Tasarımı En İyi Uygulamaları

API (Uygulama Programlama Arayüzü), bir servis sağlayıcı ile tüketicileri arasındaki bir sözleşmedir. İyi tasarlanmış bir API sezgisel, tutarlı ve kullanımı kolaydır. Kötü tasarlanmış bir API, geliştiricilerin hayal kırıklığına uğramasına, artan destek yüküne, güvenlik açıklarına ve maliyetli değişikliklere yol açar.

3 dk okumaDil: TR TürkçeÜcretsiz0 alkış0 yorum
TeknolojiMühendislik MakaleleriPlatform RehberleriDesignPracticesWeb DevelopmentTechnologyEngineering ArticlesPlatform Guides
Okuma seçenekleri

Giriş

API (Uygulama Programlama Arayüzü), bir servis sağlayıcı ile tüketicileri arasındaki bir sözleşmedir. İyi tasarlanmış bir API sezgisel, tutarlı ve kullanımı kolaydır. Kötü tasarlanmış bir API, geliştiricilerin hayal kırıklığına uğramasına, artan destek yüküne, güvenlik açıklarına ve maliyetli değişikliklere yol açar.

API'ler ürünlerdir; bunları kullanıcı arayüzleriyle aynı özenle tasarlayın. İster REST, GraphQL ister gRPC oluşturuyor olun, iyi API tasarımının ilkeleri tutarlı kalır.


RESTful API Tasarım İlkeleri

1. Kaynaklar İçin İsimleri Kullanın

Kaynaklar sisteminizdeki temel varlıklardır. Bunları fiillerle değil isimlerle adlandırın:

✅ GET /users              — List users
✅ GET /users/123          — Get user by ID
✅ POST /users             — Create user
✅ PATCH /users/123        — Partially update user
✅ PUT /users/123          — Replace user
✅ DELETE /users/123       — Delete user

❌ GET /getUser            — Verb in URL
❌ POST /createUser        — Verb in URL
❌ POST /users/create      — Verb in URL path
❌ GET /users?action=delete — Action as query parameter

2. Doğru HTTP Yöntemlerini Kullanın

Yöntem Amaç İdempotent Güvenli Vücut
ALIN Bir kaynağı alın Evet Evet Hayır
GÖNDERİM Kaynak oluştur Hayır Hayır Evet
koy Tam değiştirme Evet Hayır Evet
YAMA Kısmi güncelleme Hayır Hayır Evet
SİL Kaynağı kaldırma Evet Hayır İsteğe bağlı

Idempotent: Birden fazla özdeş istek, tek bir istekle aynı sonucu üretir.

Güvenli: Yan etkisi yoktur — önbelleğe alınabilir ve güvenli bir şekilde tekrarlanabilir.

3. Tutarlı Adlandırma Kuralları

naming_rules:
  - "Use plural nouns: /users, /orders, /products"
  - "Use kebab-case for multi-word: /order-items, /shipping-addresses"
  - "Use lowercase throughout"
  - "Nest resources logically: /users/123/orders"
  - "Avoid deep nesting (max 2-3 levels)"
  - "Use query parameters for filtering, sorting, pagination"

Yuvalama örneği:

/users/123/orders            — Orders belonging to user 123
/users/123/orders/456       — Specific order
/users/123/orders/456/items — Items in that order (okay)
/users/123/orders/456/items/789/details (too deep!)

4. API'nizi Sürümleyin

Son değişiklikler sürümü artırmalıdır:

URI sürümü oluşturma (en yaygın):

https://api.example.com/v1/users
https://api.example.com/v2/users

Başlık sürümü oluşturma:

Accept: application/vnd.example.v1+json

Aşağıdaki durumlar dışında aynı sürümdeki geriye dönük uyumluluğu asla bozmayın:

  • Kritik bir güvenlik açığı var.
  • Bir kullanımdan kaldırma politikanız var ve bunu ilettiniz.
  • Etkilenen kullanıcılar yalnızca dahili kullanıcılardır.

5. Anlamlı HTTP Durum Kodlarını Kullanın

2xx Success:
  200 OK: Generic success (GET, PATCH)
  201 Created: Resource created (POST)
  204 No Content: Success, no response body (DELETE)

3xx Redirection:
  301 Moved Permanently
  304 Not Modified (caching)

4xx Client Error:
  400 Bad Request: Malformed request, validation error
  401 Unauthorized: Missing or invalid authentication
  403 Forbidden: Authenticated but not authorized
  404 Not Found: Resource does not exist
  405 Method Not Allowed: Wrong HTTP method
  409 Conflict: Resource state conflict (duplicate, version mismatch)
  422 Unprocessable Entity: Semantic validation failure
  429 Too Many Requests: Rate limit exceeded

5xx Server Error:
  500 Internal Server Error: Unexpected server failure
  502 Bad Gateway: Upstream service failed
  503 Service Unavailable: Temporary overload/maintenance
  504 Gateway Timeout: Upstream service timed out

Talep ve Yanıt Tasarımı

Tutarlı Yanıt Zarfı

{
  "data": {
    "id": "user_123",
    "email": "john@example.com",
    "name": "John Doe",
    "created_at": "2024-01-15T10:30:00Z"
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}

Hata Yanıtları

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request body contains validation errors",
    "details": [
      {
        "field": "email",
        "message": "Email is required",
        "code": "REQUIRED_FIELD"
      },
      {
        "field": "age",
        "message": "Age must be between 18 and 120",
        "code": "INVALID_VALUE",
        "constraints": {
          "minimum": 18,
          "maximum": 120
        }
      }
    ]
  }
}

Sayfalandırma

GET /users?page=2&per_page=20&sort=created_at:desc

{
  "data": [ ... ],
  "meta": {
    "page": 2,
    "per_page": 20,
    "total": 100,
    "total_pages": 5,
    "count": 20
  },
  "links": {
    "first": "/users?page=1&per_page=20",
    "prev": "/users?page=1&per_page=20",
    "next": "/users?page=3&per_page=20",
    "last": "/users?page=5&per_page=20"
  }
}

İmleç tabanlı sayfalandırma (büyük veri kümeleri için önerilir):

GET /users?cursor=eyJpZCI6IDUwMH0=&limit=20

{
  "data": [ ... ],
  "meta": {
    "next_cursor": "eyJpZCI6IDUyMH0=",
    "has_more": true
  }
}

Filtreleme, Sıralama ve Arama

// Filtering
GET /users?role=admin&status=active
GET /orders?created_at[gte]=2024-01-01&total[gt]=100

// Sorting
GET /users?sort=name:asc,created_at:desc

// Searching
GET /users?search=john

// Field selection (sparse fields)
GET /users/123?fields=id,name,email

Kısmi Güncellemeler (PATCH ve PUT)

// PUT — Full replacement (requires all fields)
PUT /users/123
{
  "email": "newemail@example.com",
  "name": "John Updated",
  "age": 31
}

// PATCH — Partial update (only send changed fields)
PATCH /users/123
{
  "email": "newemail@example.com"
}

En İyi Güvenlik Uygulamaları

Kimlik doğrulama

Önerilen: OAuth 2.0 + OpenID Connect

POST /oauth/token
Content-Type: application/json

{
  "grant_type": "client_credentials",
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "scope": "read write"
}

Response:
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read write"
}
GET /api/users
Authorization: Bearer eyJhbGciOi...

JWT Yapısı

// Header
{
  "alg": "RS256",
  "typ": "JWT"
}

// Payload
{
  "sub": "user_123",
  "iss": "auth.example.com",
  "iat": 1705312200,
  "exp": 1705315800,
  "scope": "read:users write:users",
  "roles": ["admin"]
}

Hız Sınırlaması

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705315800
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
Content-Type: application/json

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 3600 seconds.",
    "retry_after": 3600
  }
}

Giriş Doğrulaması

// Zod validation schema for API input
import { z } from 'zod';

const createUserSchema = z.object({
  email: z.string().email('Invalid email format'),
  name: z.string().min(1, 'Name is required').max(100),
  age: z.number().int().min(18).max(120).optional(),
  role: z.enum(['user', 'admin', 'moderator']).default('user'),
  tags: z.array(z.string()).max(10).optional(),
});

// Validation middleware
function validate(schema: ZodSchema) {
  return (req, res, next) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(422).json({
        error: {
          code: 'VALIDATION_ERROR',
          message: 'Validation failed',
          details: result.error.issues.map(i => ({
            field: i.path.join('.'),
            message: i.message
          }))
        }
      });
    }
    req.validatedBody = result.data;
    next();
  };
}

HTTPS ve CORS

// CORS configuration
const corsOptions = {
  origin: [
    'https://app.example.com',
    'https://admin.example.com',
  ],
  methods: ['GET', 'POST', 'PATCH', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  exposedHeaders: ['X-RateLimit-Remaining'],
  credentials: true,
  maxAge: 86400  // Preflight cache (24 hours)
};
app.use(cors(corsOptions));

API Dokümantasyonu

OpenAPI 3.0 Spesifikasyonu

openapi: 3.0.3
info:
  title: User Management API
  version: 2.0.0
  description: API for managing users in the system
  contact:
    email: api-support@example.com

servers:
  - url: https://api.example.com/v2
    description: Production server

paths:
  /users:
    get:
      summary: List all users
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: per_page
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
      responses:
        '200':
          description: A list of users
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'

    post:
      summary: Create a new user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
      responses:
        '201':
          description: User created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '422':
          description: Validation error

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
        email:
          type: string
          format: email
        name:
          type: string
        created_at:
          type: string
          format: date-time

İnteraktif Dokümantasyon

# Serve Swagger UI for API documentation
npm install -g swagger-ui-express
# Visit: https://api.example.com/docs

API Testi

Sözleşme Testi

// Pact consumer-driven contract test
const { Pact } = require('@pact-foundation/pact');

describe('User API contract', () => {
  const provider = new Pact({
    consumer: 'Frontend App',
    provider: 'User Service',
    port: 1234,
  });

  beforeAll(() => provider.setup());

  describe('GET /users/123', () => {
    beforeAll(() => {
      return provider.addInteraction({
        state: 'User 123 exists',
        uponReceiving: 'a request for user 123',
        withRequest: {
          method: 'GET',
          path: '/users/123',
          headers: { Authorization: 'Bearer valid-token' }
        },
        willRespondWith: {
          status: 200,
          headers: { 'Content-Type': 'application/json' },
          body: {
            data: {
              id: '123',
              email: 'user@example.com',
              name: 'Test User'
            }
          }
        }
      });
    });

    it('returns the user', async () => {
      const response = await fetch('http://localhost:1234/users/123', {
        headers: { Authorization: 'Bearer valid-token' }
      });
      expect(response.status).toBe(200);
    });

    afterEach(() => provider.verify());
  });

  afterAll(() => provider.finalize());
});

GraphQL ve REST karşılaştırması

Görünüş DİNLENME GrafikQL
Veri getiriliyor Çoklu uç noktalar, sabit yanıt Tek uç nokta, müşteri tanımlı
Aşırı getiriliyor Gerekenden daha fazla veri döndürebilir Tam olarak ihtiyacınız olanı isteyin
Yeterince getirilmiyor Birden fazla istek gerekebilir (N+1) İç içe geçmiş veriler için tek istek
Önbelleğe alma Yerleşik (HTTP önbelleğe alma, CDN) Özel (Apollo önbelleği, Aktarma)
Aletleme Yetişkinlere yönelik (kıvırma, Postacı, tarayıcılar) Büyüyor (GraphiQL, Apollo DevTools)
Öğrenme eğrisi Düşük Orta
Sürüm oluşturma URI sürümü oluşturma Alan ekleyin, eskileri kullanımdan kaldırın
Dosya yükleme Yerel (çok parçalı) Özel kullanım gerektirir
Gerçek zamanlı WebSocket, SSE Abonelikler

GraphQL Ne Zaman Kullanılmalı?

  • Karmaşık, iç içe geçmiş veri gereksinimleri (kontrol panelleri, mobil uygulamalar).
  • Farklı verilere ihtiyaç duyan birden fazla istemci türü (web, mobil, IoT).
  • Hızla gelişen ön uç gereksinimleri.

REST Ne Zaman Kullanılır?

  • Basit CRUD işlemleri.
  • Geniş tüketici tabanına sahip genel API'ler.
  • Önbelleğe alma önemlidir (GET uç noktaları için CDN).
  • Dosya yüklemeleri ve ikili veriler.

API Yaşam Döngüsü Yönetimi

Sürüm Oluşturma Stratejisi

version_policy:
  - v1: Initial release (stable, deprecated)
  - v2: Current version (active development)
  - v3: Planned (future)

deprecation:
  notice_period: 6 months
  communication: email, API response header
  sunset_header: true  # Deprecation: true

transition:
  new_features: v2 only
  bug fixes: v1 critical only
  migrations: provide migration guide

Kullanımdan Kaldırma Başlıkları

GET /v1/users/123
Sunset: Sat, 30 Nov 2024 00:00:00 GMT
Deprecation: true
Link: </v2/users/123>; rel="successor-version"

Sonuç

İyi API tasarımı şu ilkeleri takip eder:

  1. Tutarlılık — Adlandırma, hata biçimleri, sayfalandırma ve kimlik doğrulama aynı kalıpları izlemelidir.
  2. Geliştirici deneyimi — Açık belgeler, öngörülebilir davranış, faydalı hata mesajları.
  3. Varsayılan olarak güvenlik — HTTPS, kimlik doğrulama, hız sınırlama, giriş doğrulama, CORS.
  4. Geriye dönük uyumluluk — Sürümü bilinçli olarak kullanın, kullanımdan kaldırın, son derece önemli değişiklikleri bildirin.
  5. Performans — Sayfalandırma, başlıkları önbelleğe alma, seyrek alanlar, sıkıştırma.

API bir üründür. Tasarımına yatırım yapın, ayrıntılı bir şekilde belgeleyin, dikkatlice sürümlendirin ve her önemli değişikliğe hak ettiği ciddiyetle yaklaşın.

Öne Çıkan Makaleler

2026’da Oluşturmaya Değer 50 Claude Skill
EditoryalTR
8 dkÜcretsiz

2026’da Oluşturmaya Değer 50 Claude Skill

Claude Skills, tekrarlanan promptları yeniden kullanılabilir workflow’lara dönüştürebilir. İşte yazma, kodlama, araştırma, iş, üretkenlik, tasarım, analiz ve destek için 50 pratik Claude Skill.

TeknolojiAIAi GuidesAI Agents
0 alkış
Oku
Senior Engineer’lardan Öğrendiğim 6 Kodlama Pattern’i
EditoryalTR
8 dkÜcretsiz

Senior Engineer’lardan Öğrendiğim 6 Kodlama Pattern’i

TeknolojiCodeProgrammingCoding
0 alkış
Oku
Özel Bir Yapay Zeka Not Asistanı Kurun
Öne çıkanTR
9 dkÜcretsiz

Özel Bir Yapay Zeka Not Asistanı Kurun

Markdown notlarını özel taslakları açığa çıkarmadan aranabilir bir asistana dönüştürün.

TeknolojiPlatform RehberleriYapay Zeka YazımıAIAutomationData
0 alkış
Oku

Yorumlar

0 yorum

Henüz onaylı yorum yok. Yeni yanıtlar moderasyon bekleyebilir.