irdaweb Bilgi Teknolojileri
Telefon numaramız +90 541 209 02 05
E-posta adresimiz [email protected]
Konu 16 · API Tasarımı & Entegrasyon

API tasarımı ve entegrasyon — istekten yanıta.

Bir API, iki sistemin birbiriyle konuşması için üzerinde anlaşılmış bir sözleşmedir. İyi tasarlanmış bir API tahmin edilebilir davranır: aynı isteğe aynı yanıtı verir, hataları açıkça anlatır ve değişirken mevcut entegrasyonları kırmaz. Bu sayfada REST kaynak modelinden HTTP metotlarına, kimlik doğrulamadan versiyonlamaya, rate limiting'den webhook entegrasyonuna kadar temel kavramları birlikte ve adım adım yan yana koyduk.

01 — API temelleri

API nedir, REST ne anlama gelir?

API (Application Programming Interface), bir yazılımın yeteneklerini başka yazılımlara açan arayüzdür. Web API'lerinin büyük bölümü REST tarzında tasarlanır: her şey bir kaynaktır (kullanıcı, sipariş, fatura), her kaynağın bir adresi (URL) vardır ve bu kaynaklar üzerinde HTTP metotlarıyla işlem yaparsınız. İstemci bir istek gönderir, sunucu bir yanıt döner; iletişim durumsuzdur, yani her istek kendi başına anlaşılır olmalıdır.

İstek istemci → sunucu
GET /v1/orders/42 HTTP/1.1
Host: api.ornek.com
Authorization: Bearer eyJhbGc...
Accept: application/json

# kaynak: 42 numaralı sipariş
Yanıt sunucu → istemci
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 42,
  "status": "shipped",
  "total": 149.90
}
Resource

Kaynak — adreslenebilir nesne

REST'te her veri parçası bir kaynaktır ve kendi URL'i vardır. /orders/42, tek bir siparişi; /orders ise koleksiyonu temsil eder.

Stateless

Durumsuzluk — her istek bağımsız

Sunucu istekler arasında oturum hatırlamaz. Kimlik ve gerekli bağlam her isteğin içinde taşınır; bu, yatay ölçeklemeyi ve önbelleklemeyi kolaylaştırır.

Representation

Temsil — genellikle JSON

Kaynağın o anki hali bir temsille (çoğunlukla JSON) taşınır. Content-Type ve Accept başlıkları formatı belirler.

02 — Metot & durum kodu

HTTP metotları, idempotency ve durum kodları

HTTP metodu, kaynak üzerinde ne yapmak istediğinizi söyler: okuma, oluşturma, güncelleme veya silme. Önemli bir ayrım idempotency'dir: aynı isteği birden çok kez göndermenin sonucu değiştirmediği metotlar (GET, PUT, DELETE) güvenle tekrar denenebilir; POST ise genellikle her çağrıda yeni bir kayıt oluşturur. Yanıtın durum kodu da en az gövde kadar önemlidir — entegrasyonlar kararlarını çoğunlukla bu koda göre verir.

Metot Amaç
GET Kaynağı okur, yan etkisi yoktur
POST Koleksiyona yeni kaynak ekler
PUT Kaynağı bütünüyle değiştirir
PATCH Kaynağın bir kısmını günceller
DELETE Kaynağı siler
2xx

Başarı

200 OK okuma/güncellemede, 201 Created oluşturmada, 204 No Content ise gövdesiz başarıda kullanılır.

4xx

İstemci hatası

400 geçersiz istek, 401 kimliksiz, 403 yetkisiz, 404 bulunamadı, 409 çakışma. Sorun isteğin kendisindedir.

5xx

Sunucu hatası

500 beklenmeyen hata, 503 geçici erişilemezlik. Burada hata sunucudadır; istemci genelde tekrar deneyebilir.

Her yanıta 200 dönmeyin. Hatayı gövdede {"error": ...} olarak verip durum kodunu 200 bırakmak, istemcinin başarı ile başarısızlığı ayırt etmesini imkânsızlaştırır. Doğru durum kodu, doğru gövdeden önce gelir.
03 — Kaynak tasarımı

URL isimlendirme, sayfalama ve filtreleme

İyi bir API, dokümantasyona bakmadan tahmin edilebilir. Bunun yolu tutarlı kaynak isimlendirmesinden geçer: çoğul isimler, fiil yerine isim, sığ ve öngörülebilir yollar. Büyük koleksiyonlar asla tek seferde dönmemeli; sayfalama, filtreleme ve sıralama net parametrelerle sunulmalıdır. Amaç, istemcinin sonraki adımı görmeden bilebilmesidir.

Tutarlı tahmin edilebilir yollar
GET    /v1/customers
POST   /v1/customers
GET    /v1/customers/17
GET    /v1/customers/17/orders
GET    /v1/orders?status=open&limit=25

# çoğul, isim, sığ; ilişki bir alt yol
Kaçının fiil + tutarsız yapı
POST   /getCustomerById
POST   /v1/createNewOrder
GET    /v1/customer/17/getOrders
GET    /v1/ALL-orders

# fiil yola girmiş, tekil/çoğul karışık,
# metot ile amaç çelişiyor

Sayfalama

Büyük listeleri parçalayın. Offset tabanlı (?page=2) basittir; cursor tabanlı (?cursor=...) ise sık değişen verilerde kaymayı önler.

Filtreleme & sıralama

Sorgu parametreleriyle daraltma sunun: ?status=open, ?sort=-created_at. Parametre adlarını alan adlarıyla tutarlı tutun.

Tutarlı zarf

Liste yanıtlarını sabit bir yapıyla dönün: veri dizisi ve yanında toplam sayı, sonraki sayfa bilgisi. İstemci her endpoint için yeniden öğrenmek zorunda kalmaz.

04 — Kimlik & yetki

API key, OAuth 2.0 ve bearer token

API'nin önce kimi dinlediğini (authentication), sonra neye izin verdiğini (authorization) bilmesi gerekir. Sunucu-sunucu entegrasyonlarda API key veya istemci kimlik bilgisi yeterken; bir kullanıcı adına erişim için OAuth 2.0 ile alınan bearer token kullanılır. İzinler scope'larla daraltılır, böylece bir anahtar yalnızca işini yapacak kadar yetki taşır.

OAuth 2.0 client credentials akışı
# 1) Token al
POST /oauth/token
  grant_type=client_credentials
  client_id=abc&client_secret=***
  scope=orders:read

# 2) Token ile isteği imzala
GET /v1/orders
Authorization: Bearer eyJhbGc...
API key
Sabit, uzun ömürlü bir gizli anahtar. Kurulumu kolaydır ama sızması hâlinde tek başına tam erişim verir; bu yüzden yetkisi dar tutulmalı ve düzenli döndürülmelidir.
Bearer token
Kısa ömürlü erişim jetonu. "Taşıyan kullanır" mantığıyla çalışır; bu nedenle yalnızca TLS üzerinden taşınmalı ve süresi kısa tutulmalıdır. Süre dolunca refresh token ile yenilenir.
Scope
Token'ın neye eriştiğini sınırlar (orders:read, invoices:write). En az yetki ilkesini uygulamanın pratik yoludur.
mTLS / imza
Yüksek güven gereken entegrasyonlarda istemci sertifikası (mTLS) veya istek imzalama eklenir; böylece token çalınsa bile başka bir istemciden kullanılamaz.
05 — Versiyonlama & sözleşme

OpenAPI sözleşmesi ve kırıcı değişiklikler

Bir API yayımlandığı andan itibaren bir sözdür: başka ekipler ona göre kod yazar. Bu yüzden API'nizi makine-okunur bir sözleşmeyle (OpenAPI) tanımlamak ve değişiklikleri "kırıcı" mı değil mi diye sınıflandırmak kritiktir. Alan eklemek genelde güvenlidir; alan silmek, yeniden adlandırmak veya zorunlu kılmak ise mevcut istemcileri kırar ve yeni bir sürüm gerektirir.

openapi.yaml
openapi: 3.1.0
info:
  title: Orders API
  version: 1.4.0
paths:
  /orders/{id}:
    get:
      summary: Tek sipariş getir
      responses:
        "200": { description: Başarılı }
        "404": { description: Bulunamadı }

Tek bir sözleşme dosyasından dokümantasyon, istemci kütüphaneleri ve sözleşme testleri üretebilirsiniz. Sözleşme koddan ayrı yaşadığında, dokümantasyon ile gerçek davranış arasındaki sapma görünür olur.

  • v1 → v2URL ile versiyonlama

    /v1/... ve /v2/... yan yana yaşar. En görünür ve en yaygın yöntemdir; eski sürüm bir süre desteklenmeye devam eder.

  • GüvenliKırmayan değişiklik

    İsteğe bağlı yeni alan eklemek, yeni endpoint açmak, yeni opsiyonel parametre eklemek. Mevcut istemciler etkilenmeden çalışmaya devam eder.

  • DeprecationAşamalı emeklilik

    Bir alanı kaldırmadan önce duyurun, Deprecation başlığıyla işaretleyin ve geçiş için makul süre tanıyın.

06 — Rate limit & webhook

Rate limiting, retry, idempotency ve webhook

Ağ güvenilmezdir: istekler kaybolur, gecikir veya tekrarlanır. Sağlam bir entegrasyon bunu varsayar. Sunucu tarafında rate limiting kötüye kullanımı sınırlar; istemci tarafında retry ve exponential backoff geçici hataları toparlar. İkisinin ortasında idempotency key durur: aynı isteğin iki kez işlenmesini önler. Diğer yönde ise webhook'lar, sizin sormanızı beklemeden olayları size iter.

429 rate limit yanıtı
HTTP/1.1 429 Too Many Requests
Retry-After: 2
RateLimit-Remaining: 0
RateLimit-Reset: 2

# istemci 2 sn bekleyip tekrar dener
Idempotent POST çift işlemeyi önler
POST /v1/payments
Idempotency-Key: a1b2-c3d4

# aynı key ile gelen ikinci istek
# yeni ödeme oluşturmaz; ilk yanıtı döner
Webhook imza doğrulama
# sağlayıcı sizin URL'inize olayı iter
POST /webhooks/payments
X-Signature: sha256=9f86d0...

{ "event": "payment.succeeded",
  "id": "evt_123" }

# 1) imzayı paylaşılan sır ile doğrula
# 2) hızlıca 200 dön, işi kuyruğa al

İmzayı doğrulayın

Gelen webhook'un gerçekten sağlayıcıdan geldiğini, paylaşılan sırla hesaplanan imzayı karşılaştırarak doğrulayın. İmzasız bir uca güvenmeyin.

Tekrarlara hazır olun

Webhook'lar en az bir kez teslim edilir; aynı olay iki kez gelebilir. Olay kimliğini saklayıp işlenmişse atlayın — alıcı tarafı idempotent olmalı.

07 — Güvenlik & işletim

TLS, girdi doğrulama, CORS ve observability

API güvenliği tek bir önlemle değil, üst üste binen katmanlarla sağlanır: her isteği TLS üzerinden taşımak, gelen her girdiyi doğrulamak, yetkiyi kaynak düzeyinde kontrol etmek ve tarayıcı erişimini CORS ile bilinçli açmak. Üzerine de işletim gelir — her isteği ölçmeden hangi entegrasyonun yavaşladığını ya da hata aldığını göremezsiniz.

TLS

Her zaman HTTPS

Token ve veri yalnızca şifreli kanaldan taşınmalı. Düz HTTP'yi kapatın; bearer token gibi gizli değerler asla şifresiz ağda dolaşmamalı.

Validation

Gelen girdiye güvenmeyin

Her alanı tip, uzunluk ve aralık olarak doğrulayın; beklenmeyen alanları reddedin. Sözleşmeye uymayan istek, iş mantığına ulaşmadan durmalı.

AuthZ

Nesne düzeyinde yetki

Kimliği doğrulanmış olmak yetmez. /orders/42 isteyen kullanıcının o siparişe erişebildiğini her seferinde kontrol edin — aksi hâlde bilgi sızar.

CORS

Tarayıcı erişimini bilinçli açın

Tarayıcıdan çağrılacaksa yalnızca güvendiğiniz origin'lere izin verin. * ile her yere açmak, kötü amaçlı sitelerin API'nizi kullanmasına kapı aralar.

Secrets

Anahtarları koddan ayırın

API key ve client secret'ları depoya commit etmeyin. Ortam değişkeni ya da bir secrets manager kullanın; sızıntıya karşı düzenli rotasyon planlayın.

Observability

Her isteği ölçün

Gecikme, hata oranı ve trafik hacmini endpoint bazında izleyin. Correlation ID'leri ile bir isteğin uçtan uca yolunu takip edin; sorun çıktığında nedeni hızlı bulun.

En sık görülen API açığı, eksik yetki kontrolüdür. Kimlik doğrulama ile yetkilendirme aynı şey değildir. Kullanıcının giriş yapmış olması, istediği her kaynağa erişebileceği anlamına gelmez; yetkiyi her istekte, kaynağın kendisi üzerinde kontrol edin.
08 — Sık karıştırılanlar

Sık karıştırılan API kavramları

Authentication vs. Authorization

Authentication "sen kimsin?" sorusunu yanıtlar — kimliği doğrular. Authorization ise "neye iznin var?" sorusunu — yetkiyi belirler. Önce kimlik doğrulanır, sonra her kaynak için yetki kontrol edilir; biri diğerinin yerine geçmez.

PUT vs. PATCH

PUT kaynağı bütünüyle değiştirir; gönderdiğiniz gövde kaynağın yeni tam halidir. PATCH ise yalnızca belirttiğiniz alanları günceller. Bir alanı yanlışlıkla boşaltmamak için kısmi güncellemede PATCH tercih edilir.

401 vs. 403

401 Unauthorized aslında "kimliğin yok ya da geçersiz" demektir — giriş yapmanız gerekir. 403 Forbidden ise "kimliğin var ama bu kaynağa yetkin yok" anlamına gelir. İsimleri yanıltıcı olsa da ayrım kimlik ile yetki arasındadır.

REST vs. GraphQL

REST her kaynağı ayrı bir endpoint olarak sunar; istemci sabit yanıtları alır. GraphQL tek bir uçtan, istemcinin tam olarak istediği alanları sorgulamasına izin verir. Biri basitlik ve önbellekleme, diğeri esneklik tarafında güçlüdür; rakip değil, farklı denge noktalarıdır.

Idempotent vs. Safe

Safe metot kaynağı hiç değiştirmez (GET). Idempotent metot ise değiştirebilir ama aynı isteği tekrarlamak ek bir etki yaratmaz (PUT, DELETE). Her safe metot idempotenttir; ama her idempotent metot safe değildir.

Birinci el kaynaklar

HTTP, OAuth ve API güvenliğini tanımlayan IETF, OWASP ve OpenAPI gibi kuruluşların resmi belgeleri.

Sıradaki adım

API'nizi birlikte tasarlayalım.

Sıfırdan bir API tasarlamaktan mevcut bir entegrasyonu sağlamlaştırmaya kadar; baştan iyi kurulmuş bir sözleşme, sonradan toparlamaktan her zaman kolaydır. Nereden başlayacağınıza birlikte bakalım.