API Entegrasyonuna Giriş: Temel Kavramlar ve HTTP
Modern yazılım dünyasında hiçbir sistem artık tek başına çalışmıyor. Kullandığın bulut servisleri, izleme araçları, otomasyon scriptleri ve iş uygulamaları birbirleriyle konuşmak zorunda. Bu konuşmanın dili ise büyük ölçüde API’ler. Sysadmin olarak sen de er ya da geç bir servisi başka bir servisle entegre etmen, bir REST endpoint’ine veri çekmen ya da kendi yazdığın scriptten bir platforma veri göndermenin yolunu bulman gerekecek. Bu yazıda API dünyasına pratik bir giriş yapıyoruz; teorik olmayan, gerçekten kullanabileceğin bilgilerle.
API Nedir ve Neden Önemli
API, “Application Programming Interface” kelimelerinin kısaltması. Türkçeye “Uygulama Programlama Arayüzü” diye çeviriyorlar ama bu çeviri pek bir şey ifade etmiyor açıkçası. Daha anlaşılır şekilde söylersek: API, iki yazılımın birbirleriyle nasıl konuşacağını tanımlayan bir sözleşme.
Restoran analojisini herkes yapar ama çünkü gerçekten işe yarıyor: Mutfağa gidip yemek istemiyorsun, garsonla konuşuyorsun. Garson senin isteğini mutfağa iletiyor, mutfak hazırlıyor, garson sana getiriyor. Burada garson API, mutfak ise arka taraftaki sistem. Sen mutfağın nasıl çalıştığını bilmek zorunda değilsin.
Sysadmin perspektifinden bakınca API’lerin önemi şu noktalarda ortaya çıkıyor:
- Otomasyon: Monitoring sisteminin alert’lerini Slack kanalına göndermek
- Entegrasyon: CMDB’den sunucu listesi çekip Ansible inventory oluşturmak
- Raporlama: Cloud provider’dan maliyet verilerini çekip kendi dashboard’una yazmak
- Webhook: Bir event gerçekleştiğinde başka bir sistemi tetiklemek
HTTP Protokolünün Temelleri
REST API’lerin büyük çoğunluğu HTTP protokolü üzerinde çalışıyor. HTTP’yi sadece web sayfası yüklemek için düşünme, aslında çok daha güçlü bir veri transfer protokolü.
HTTP Methods (HTTP Metodları)
Her HTTP isteği bir metod içeriyor. Bu metod yapılan işlemin ne olduğunu söylüyor:
- GET: Veri okuma. Sunucuda hiçbir şey değişmiyor, sadece okuyorsun.
- POST: Yeni kayıt oluşturma. Sunucuya yeni veri gönderiyorsun.
- PUT: Var olan kaydı tamamen güncelleme. Tüm alanları yeniden yazıyorsun.
- PATCH: Var olan kaydın bir kısmını güncelleme. Sadece değişen alanları gönderiyorsun.
- DELETE: Kayıt silme.
- HEAD: GET gibi ama response body dönmüyor, sadece header’lar geliyor. Dosya boyutu kontrol etmek için kullanışlı.
- OPTIONS: Endpoint’in hangi metodları desteklediğini öğrenmek için.
HTTP Status Kodları
API response’larını anlamak için status kodlarını iyi bilmen gerekiyor:
- 200 OK: Her şey yolunda, istek başarılı.
- 201 Created: Yeni kayıt başarıyla oluşturuldu.
- 204 No Content: Başarılı ama dönecek bir şey yok (genellikle DELETE sonrası).
- 400 Bad Request: Gönderdiğin istek hatalı, eksik ya da format yanlış.
- 401 Unauthorized: Kimlik doğrulama gerekli veya token geçersiz.
- 403 Forbidden: Kimliğin doğrulandı ama bu kaynağa erişim iznin yok.
- 404 Not Found: İstediğin kaynak bulunamadı.
- 409 Conflict: Çakışma var, örneğin aynı isimle kayıt zaten mevcut.
- 422 Unprocessable Entity: İstek formatı doğru ama içerik işlenemiyor.
- 429 Too Many Requests: Rate limit aştın, yavaşla.
- 500 Internal Server Error: Sunucu tarafında bir şeyler patladı.
- 502 Bad Gateway: Ara sunucu upstream’den geçersiz yanıt aldı.
- 503 Service Unavailable: Servis şu an çalışmıyor.
HTTP Headers
Header’lar istek ve yanıt hakkında meta bilgi taşıyor:
- Content-Type: Gönderdiğin verinin formatı.
application/json,text/plain,multipart/form-datagibi. - Accept: Hangi formatta yanıt istediğini belirtiyorsun.
- Authorization: Kimlik doğrulama bilgisi.
Bearer TOKENya daBasic base64encodedformatında. - X-API-Key: Bazı API’ler token’ı bu header’da bekliyor.
- Content-Length: Gönderilen verinin byte cinsinden boyutu.
- Cache-Control: Cache davranışını kontrol ediyor.
curl ile API Çağrıları
curl her sysadmin’in silahı. API test etmek için en hızlı araç:
# Basit GET isteği
curl https://jsonplaceholder.typicode.com/users/1
# Pretty print için jq ile birlikte kullan
curl -s https://jsonplaceholder.typicode.com/users/1 | jq .
# Verbose mod - header'ları ve tüm detayları görmek için
curl -v https://jsonplaceholder.typicode.com/users/1
# Sadece response header'larını göster
curl -I https://jsonplaceholder.typicode.com/users/1
# Custom header ekle
curl -H "Accept: application/json"
-H "X-Custom-Header: my-value"
https://api.example.com/data
# POST isteği - JSON body ile
curl -X POST https://jsonplaceholder.typicode.com/posts
-H "Content-Type: application/json"
-d '{"title": "Test Post", "body": "Content here", "userId": 1}'
# Authorization header ile
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.your-token"
https://api.example.com/protected/resource
# PUT isteği
curl -X PUT https://jsonplaceholder.typicode.com/posts/1
-H "Content-Type: application/json"
-d '{"id": 1, "title": "Updated Title", "body": "Updated body", "userId": 1}'
# DELETE isteği
curl -X DELETE https://jsonplaceholder.typicode.com/posts/1
-w "nHTTP Status: %{http_code}n"
curl’ün Önemli Parametreleri
- -X: HTTP metodunu belirt (GET, POST, PUT, DELETE)
- -H: Header ekle
- -d: Request body gönder (data)
- -s: Silent mod, progress bar gösterme
- -v: Verbose, tüm detayları göster
- -I: Sadece header’ları al (HEAD metodu)
- -L: Redirect’leri takip et
- -o dosya: Çıktıyı dosyaya yaz
- -w: Belirli bilgileri formatlı yaz (http_code, time_total gibi)
- -k: SSL sertifika doğrulamasını atla (sadece test ortamında!)
- –max-time: Maksimum süre sınırı
Authentication Yöntemleri
API’lerde kimlik doğrulama birkaç farklı şekilde yapılıyor:
API Key
En basit yöntem. Bir string, bir header ya da query parameter olarak gönderiyorsun:
# Header üzerinden
curl -H "X-API-Key: sk-1234567890abcdef"
https://api.example.com/data
# Query parameter olarak (daha az güvenli)
curl "https://api.example.com/data?api_key=sk-1234567890abcdef"
# Örnek: OpenWeatherMap API
curl -s "https://api.openweathermap.org/data/2.5/weather?q=Istanbul&appid=YOUR_API_KEY" | jq '.main'
Basic Auth
Username ve password’ü base64 encode edip Authorization header’ına koyuyorsun:
# curl'ün -u parametresi bunu otomatik yapıyor
curl -u username:password https://api.example.com/resource
# Manuel olarak
echo -n "username:password" | base64
# Çıktı: dXNlcm5hbWU6cGFzc3dvcmQ=
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ="
https://api.example.com/resource
Bearer Token / JWT
Modern API’lerin büyük çoğunluğu bu yöntemi kullanıyor:
# Token'ı önce environment variable'a al, scripte gömme
export API_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -H "Authorization: Bearer $API_TOKEN"
https://api.example.com/protected
# Token expire oluyorsa, refresh token ile yeni token al
curl -X POST https://api.example.com/auth/refresh
-H "Content-Type: application/json"
-d "{"refresh_token": "$REFRESH_TOKEN"}"
Python ile API Entegrasyonu
Bash ile basit işler yapabilirsin ama daha karmaşık senaryolar için Python çok daha uygun. requests kütüphanesi bu iş için standart:
# requests kütüphanesini kur
pip3 install requests
# Virtual environment kullanmak daha iyi pratik
python3 -m venv api-env
source api-env/bin/activate
pip install requests
import requests
import json
import os
# API base URL'ini ve token'ı environment'dan al
BASE_URL = "https://api.example.com/v1"
API_TOKEN = os.environ.get("API_TOKEN")
# Session kullanmak performansı artırıyor
session = requests.Session()
session.headers.update({
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json"
})
# GET isteği
def get_servers():
response = session.get(f"{BASE_URL}/servers")
# Status code kontrol et
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
raise Exception("Authentication failed. Token geçersiz veya expire olmuş.")
elif response.status_code == 429:
retry_after = response.headers.get("Retry-After", 60)
raise Exception(f"Rate limit aşıldı. {retry_after} saniye bekle.")
else:
raise Exception(f"API hatası: {response.status_code} - {response.text}")
# POST isteği - yeni sunucu ekle
def create_server(name, region, size):
payload = {
"name": name,
"region": region,
"size": size
}
response = session.post(f"{BASE_URL}/servers", json=payload)
response.raise_for_status() # 4xx/5xx'te exception fırlat
return response.json()
# Hata yönetimi ile daha sağlam kullanım
try:
servers = get_servers()
print(f"Toplam {len(servers)} sunucu bulundu")
for server in servers:
print(f" - {server['name']} ({server['region']})")
except requests.exceptions.ConnectionError:
print("API'ye bağlanılamadı. Network bağlantısını kontrol et.")
except requests.exceptions.Timeout:
print("İstek zaman aşımına uğradı.")
except Exception as e:
print(f"Hata: {e}")
Gerçek Dünya Senaryosu: Slack’e Alert Gönderme
Monitoring scriptine Slack entegrasyonu eklemek çok yaygın bir ihtiyaç. Slack’in Incoming Webhooks özelliği bunun en kolay yolu:
#!/bin/bash
# slack-alert.sh - Disk kullanımı yüksekse Slack'e bildir
WEBHOOK_URL="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXX"
THRESHOLD=85
HOSTNAME=$(hostname)
# Disk kullanımını kontrol et
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt "$THRESHOLD" ]; then
# Slack mesajı için JSON payload oluştur
PAYLOAD=$(cat <<EOF
{
"text": ":warning: Disk Uyarısı",
"attachments": [
{
"color": "danger",
"fields": [
{
"title": "Sunucu",
"value": "$HOSTNAME",
"short": true
},
{
"title": "Disk Kullanımı",
"value": "%$DISK_USAGE",
"short": true
}
],
"footer": "$(date '+%Y-%m-%d %H:%M:%S')"
}
]
}
EOF
)
# Webhook'a gönder
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}"
-X POST "$WEBHOOK_URL"
-H "Content-Type: application/json"
-d "$PAYLOAD")
if [ "$RESPONSE" == "200" ]; then
echo "Slack bildirimi gönderildi"
else
echo "Slack bildirimi gönderilemedi. HTTP: $RESPONSE"
exit 1
fi
fi
Rate Limiting ve Retry Mantığı
Gerçek dünya API entegrasyonlarında en sık karşılaşılan sorunlardan biri rate limiting. İyi yazılmış bir script bunu handle etmeli:
#!/usr/bin/env python3
import requests
import time
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def api_request_with_retry(url, headers, max_retries=3, backoff_factor=2):
"""
Retry ve exponential backoff ile API isteği.
Rate limit durumunda otomatik bekleyip tekrar dener.
"""
for attempt in range(max_retries):
try:
response = requests.get(url, headers=headers, timeout=30)
# Rate limit
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
logger.warning(f"Rate limit. {retry_after} saniye bekleniyor...")
time.sleep(retry_after)
continue
# Geçici sunucu hatası - retry mantıklı
if response.status_code in [500, 502, 503, 504]:
wait_time = backoff_factor ** attempt
logger.warning(f"Sunucu hatası {response.status_code}. {wait_time}s sonra tekrar denenecek...")
time.sleep(wait_time)
continue
# Başarılı ya da kalıcı hata - döndür
return response
except requests.exceptions.Timeout:
wait_time = backoff_factor ** attempt
logger.warning(f"Timeout. {wait_time}s sonra tekrar denenecek...")
time.sleep(wait_time)
except requests.exceptions.ConnectionError as e:
logger.error(f"Bağlantı hatası: {e}")
raise
raise Exception(f"{max_retries} deneme sonrası başarısız")
# Kullanım
headers = {"Authorization": f"Bearer {os.environ['API_TOKEN']}"}
response = api_request_with_retry(
"https://api.example.com/data",
headers=headers,
max_retries=3
)
data = response.json()
JSON ile Çalışmak
API’lerin büyük çoğunluğu JSON formatında veri dönüyor. Bash tarafında jq, Python tarafında json modülü hayat kurtarıyor:
# jq ile JSON parse etme
# Belirli bir alanı çek
curl -s https://jsonplaceholder.typicode.com/users/1 | jq '.name'
# Array'i iterate et
curl -s https://jsonplaceholder.typicode.com/users | jq '.[].email'
# Filtreleme - sadece belirli kullanıcıları al
curl -s https://jsonplaceholder.typicode.com/users |
jq '.[] | select(.address.city == "Gwenborough") | .name'
# Yeni bir yapıya dönüştür
curl -s https://jsonplaceholder.typicode.com/users |
jq '[.[] | {name: .name, email: .email, city: .address.city}]'
# Bash script içinde JSON oluştur - printf kullanmak daha güvenli
SERVER_NAME="web-01"
IP_ADDRESS="192.168.1.10"
JSON_PAYLOAD=$(printf '{"name":"%s","ip":"%s"}' "$SERVER_NAME" "$IP_ADDRESS")
echo "$JSON_PAYLOAD"
API Dokümantasyonu Okuma
Iyi API’lerin dokümantasyonu genellikle Swagger/OpenAPI formatında. Birkaç şeye dikkat et:
- Base URL: Tüm endpoint’lerin önüne gelen adres. Versiyon numarasını içeriyor mu? (
/v1,/v2) - Authentication: Nasıl kimlik doğrulama yapman gerekiyor?
- Rate Limits: Dakika/saat/gün başına kaç istek yapabiliyorsun?
- Pagination: Çok sayıda kayıt döndüren endpoint’ler nasıl sayfalama yapıyor?
- Error Codes: API’ye özgü hata kodları var mı?
Pagination için dikkatli ol, çünkü sadece ilk sayfayı çekip işin bittiğini sanmak sık yapılan bir hata:
#!/bin/bash
# Tüm sayfaları çek ve birleştir
PAGE=1
ALL_DATA="[]"
API_URL="https://api.example.com/servers"
HEADERS=(-H "Authorization: Bearer $API_TOKEN" -H "Accept: application/json")
while true; do
RESPONSE=$(curl -s "${HEADERS[@]}" "$API_URL?page=$PAGE&per_page=100")
# Dönen kayıt sayısını kontrol et
COUNT=$(echo "$RESPONSE" | jq 'length')
if [ "$COUNT" -eq 0 ]; then
echo "Sayfa $PAGE boş. Toplam sayfa: $((PAGE-1))"
break
fi
echo "Sayfa $PAGE: $COUNT kayıt"
# jq ile birleştir
ALL_DATA=$(echo "$ALL_DATA $RESPONSE" | jq -s 'add')
PAGE=$((PAGE + 1))
sleep 0.5 # Rate limit için biraz bekle
done
echo "Toplam kayıt: $(echo "$ALL_DATA" | jq 'length')"
Güvenlik Pratikleri
API entegrasyonlarında güvenlik ihmal edilmemeli:
- Token’ları asla koda gömme: Environment variable veya secret management aracı kullan (HashiCorp Vault, AWS Secrets Manager)
- HTTPS kullan: HTTP üzerinden kimlik bilgisi gönderme
- SSL doğrulamayı atlatma:
-kya daverify=Falsesadece geliştirme ortamında - Minimal yetki ilkesi: API key’ine sadece ihtiyaç duyduğu izinleri ver
- Token rotasyonu: Uzun süre aynı token’ı kullanma, düzenli döndür
- Logları filtrele: Token’ların log dosyalarına yazılmamasına dikkat et
# Token'ı environment variable olarak set et
export API_TOKEN=$(cat /run/secrets/api_token)
# Direkt scripte yazma - YANLIŞ
# API_TOKEN="sk-12345" # Bu satırı asla koda yazma
# Log'larda token maskele
curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com/data
2>&1 | sed 's/Authorization: Bearer [^ ]*/Authorization: Bearer [MASKED]/g'
Sonuç
API entegrasyonu artık sysadmin işinin ayrılmaz bir parçası. Bulut altyapıları, DevOps araçları ve modern servisler tamamen API üzerine kurulu. Bu temelleri kavradıktan sonra CMDB’ni otomatik güncelleyen, monitoring alert’lerini birden fazla kanala ileten, cloud maliyetlerini analiz eden güçlü otomasyon scriptleri yazabilirsin.
Başlamak için en iyi yol pratik yapmak. jsonplaceholder.typicode.com gibi ücretsiz test API’leri var, hemen curl ile denemeye başlayabilirsin. GitHub API, GitLab API ya da kullandığın cloud provider’ın API’si de mükemmel pratik ortamlar sunuyor.
Bir sonraki adım olarak REST API mimarisi, webhook’lar ve OAuth 2.0 akışları konularına bakmanı öneririm. Ama onlardan önce bugün öğrendiklerini bir script’te kullanmaya çalış. Öğrenmenin en hızlı yolu bu.
