HTTPie ile Modern HTTP İstemcisi Kullanımı ve REST API Testi
Yıllarca curl kullandım, hala da kullanıyorum ama artık günlük API testlerimin büyük çoğunluğunu httpie ile yapıyorum. Nedeni basit: curl ile bir POST isteği atmak için 3-4 flag ezberlemeniz gerekiyor, httpie’de ise neredeyse düz İngilizce yazıyorsunuz. Bu yazıda httpie’yi sıfırdan ele alacağız, gerçek senaryolarla REST API testini ve günlük kullanımını inceleyeceğiz.
HTTPie Nedir ve Neden Kullanmalısınız
HTTPie, Python ile yazılmış modern bir komut satırı HTTP istemcisidir. Curl’ün yerini almaktan ziyade, geliştiriciler ve sistem yöneticileri için okunabilirliği ön plana çıkaran bir araç olarak konumlanıyor. Syntax renklendirmesi, JSON desteği, oturum yönetimi ve eklenti sistemi ile öne çıkıyor.
Şunu söyleyeyim: Production ortamında bir API’nin neden hatalı cevap verdiğini araştırıyorsunuz, acele ediyorsunuz ve terminalden hızlıca bir istek atmanız gerekiyor. Curl ile o anda Content-Type header’ını nasıl yazacağınızı, body’yi nasıl formatlayacağınızı düşünmek zorunda kalıyorsunuz. HTTPie’de bu sıkıntı yok.
Temel avantajları:
- Renkli ve formatlanmış çıktı (JSON otomatik güzelleştirme)
- İnsan dostu sözdizimi
- Oturum desteği (cookie ve header’ları session bazında saklama)
- Form ve JSON gönderimi için ayrı notasyon
- Dosya yükleme desteği
- HTTPS doğrulama kontrolü
- Plugin sistemi
Kurulum
Farklı platformlarda kurulum oldukça basit:
# Ubuntu/Debian
sudo apt update && sudo apt install httpie
# RHEL/CentOS/Rocky Linux
sudo dnf install httpie
# macOS (Homebrew)
brew install httpie
# pip ile (her platform)
pip install httpie
# pipx ile (izole ortam, önerilen)
pipx install httpie
Kurulumdan sonra http komutu ile erişebilirsiniz. Bazı sistemlerde https komutu da otomatik olarak gelir (HTTPS kısayolu olarak).
# Versiyon kontrolü
http --version
# Yardım
http --help
Temel Kullanım
HTTPie sözdizimi şu şekilde:
http [METOD] URL [ÖĞELER...]
En basit GET isteği:
# Basit GET
http GET https://jsonplaceholder.typicode.com/posts/1
# Metod belirtmezseniz GET kabul eder
http https://jsonplaceholder.typicode.com/posts/1
# Sadece body çıktısı (header olmadan)
http --body https://jsonplaceholder.typicode.com/posts/1
Çıktıda hem istek hem yanıt header’larını, hem de güzelleştirilmiş JSON body’yi göreceksiniz. İlk kez kullandığınızda bu kadar temiz bir çıktıya alışmak biraz zaman alıyor.
Header, Query String ve Authentication
# Custom header eklemek: isim:değer notasyonu
http GET https://api.example.com/users
Authorization:"Bearer eyJhbGc..."
Accept:application/json
X-Request-ID:abc123
# Query string parametreleri: isim==değer notasyonu
http GET https://api.example.com/users
page==2
per_page==20
status==active
# Basic Auth
http -a kullanici:sifre GET https://api.example.com/protected
# Digest Auth
http --auth-type=digest -a kullanici:sifre GET https://api.example.com/digest
Notasyona dikkat edin, bu httpie’nin en önemli özelliklerinden biri:
- : (tek noktalı virgül) header için
- == (çift eşittir) query string için
- = (tek eşittir) JSON/form string değeri için
- := (iki noktalı eşittir) JSON için raw değer (sayı, boolean, array) için
POST, PUT, PATCH İstekleri ve JSON Gönderimi
# JSON POST - otomatik Content-Type: application/json ekler
http POST https://jsonplaceholder.typicode.com/posts
title="HTTPie Test Yazisi"
body="Bu bir test icerigi"
userId:=1
# Nested JSON ve array göndermek
http POST https://api.example.com/orders
customer_id:=42
items:='[{"product_id": 1, "qty": 2}, {"product_id": 5, "qty": 1}]'
metadata:='{"source": "web", "campaign": "summer2024"}'
# PUT isteği
http PUT https://jsonplaceholder.typicode.com/posts/1
id:=1
title="Guncellenmis Baslik"
body="Guncellenmis icerik"
userId:=1
# PATCH - kısmi güncelleme
http PATCH https://jsonplaceholder.typicode.com/posts/1
title="Sadece Baslik Degisti"
Form verisi göndermek için --form ya da -f flag’ini kullanıyorsunuz:
# Form POST (application/x-www-form-urlencoded)
http --form POST https://httpbin.org/post
username=admin
password=secret123
remember_me=true
# Multipart form (dosya yükleme)
http --form POST https://api.example.com/upload
file@/home/user/rapor.pdf
description="Aylik rapor"
category=finance
Gerçek Dünya Senaryosu 1: Servis Sağlık Kontrolü Script’i
Diyelim ki birden fazla microservice’iniz var ve bunların health endpoint’lerini hızlıca kontrol etmeniz gerekiyor. Bash script ile httpie’yi birleştirince oldukça temiz bir çözüm çıkıyor:
#!/bin/bash
SERVICES=(
"api-gateway:https://api-gateway.internal/health"
"auth-service:https://auth.internal/health"
"payment-service:https://payment.internal/health"
"notification-service:https://notify.internal/health"
)
FAILED=0
for service_entry in "${SERVICES[@]}"; do
service_name="${service_entry%%:*}"
service_url="${service_entry#*:}"
response=$(http --check-status --timeout=5 GET "$service_url" 2>&1)
exit_code=$?
if [ $exit_code -eq 0 ]; then
status=$(echo "$response" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status','unknown'))" 2>/dev/null)
echo "[OK] $service_name - Status: ${status:-up}"
else
echo "[FAIL] $service_name - Yanit alinamadi veya hata kodu dondu"
FAILED=$((FAILED + 1))
fi
done
echo ""
echo "Toplam: ${#SERVICES[@]} servis, $FAILED adet basarisiz"
exit $FAILED
--check-status flag’i önemli: HTTP 4xx veya 5xx dönerse script exit code olarak hata veriyor, böylece CI/CD pipeline’ınızda bunu yakalayabiliyorsunuz.
Oturum Yönetimi
HTTPie’nin bence en underrated özelliği oturum desteği. Bir kez giriş yapıyorsunuz, cookie ve header’lar otomatik saklanıyor:
# İlk istek: giriş ve session oluşturma
http --session=myapi POST https://api.example.com/auth/login
username=admin
password=supersecret
# Sonraki isteklerde session kullanma (token/cookie otomatik gönderilir)
http --session=myapi GET https://api.example.com/dashboard
http --session=myapi GET https://api.example.com/users
# Session dosyasını görmek (hangi bilgilerin saklandığını anlamak için)
cat ~/.config/httpie/sessions/api.example.com/myapi.json
Session dosyaları JSON formatında saklanıyor ve içinde header’lar, cookie’ler, auth bilgileri bulunuyor. Bu özellik özellikle staginge karşı manuel testler yaparken inanılmaz zaman kazandırıyor.
Gerçek Dünya Senaryosu 2: Token Bazlı API Testi
JWT bearer token kullanan bir API’yi test ederken tipik akış şöyle:
# 1. Token al
TOKEN=$(http POST https://api.example.com/auth/token
grant_type=client_credentials
client_id=myapp
client_secret=gizlisifre
--body | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
echo "Token alindi: ${TOKEN:0:20}..."
# 2. Token ile istek at
http GET https://api.example.com/api/v1/customers
"Authorization:Bearer $TOKEN"
page==1
limit==50
# 3. Oluşturma isteği
http POST https://api.example.com/api/v1/customers
"Authorization:Bearer $TOKEN"
name="Test Musterisi"
email="[email protected]"
phone="+905551234567"
tier:=2
active:=true
Çıktı Kontrolü ve Debug
# Sadece response header'larını gör
http --headers GET https://api.example.com/users
# Sadece response body'yi gör
http --body GET https://api.example.com/users
# Verbose mod: istek + yanıt tamamı
http --verbose GET https://api.example.com/users
# Çok daha detaylı debug (TLS bilgisi dahil)
http --debug GET https://api.example.com/users
# Gerçekte ne gönderdiğini gör ama isteği ATMA (dry-run)
http --offline POST https://api.example.com/users
name="Test"
email="[email protected]"
# Response'u dosyaya kaydet
http GET https://api.example.com/report/monthly
"Authorization:Bearer $TOKEN"
--output monthly_report.json
# İlerleme çubuğu ile büyük dosya indir
http --download GET https://releases.example.com/app-v2.1.tar.gz
--offline modu çok işe yarıyor: İsteği gerçekten göndermeden önce nasıl görüneceğini kontrol edebiliyorsunuz. Özellikle auth header’larını veya body formatını doğrulamak için ideal.
HTTPS ve Sertifika Yönetimi
# Self-signed sertifika doğrulamasını atla (test ortamları için)
http --verify=no GET https://staging-internal.example.com/api/health
# Özel CA sertifikası kullan
http --verify=/etc/ssl/certs/internal-ca.crt GET https://internal-api.example.com/
# Client sertifikası ile mutual TLS
http --cert=/path/to/client.crt
--cert-key=/path/to/client.key
GET https://api.example.com/secure-endpoint
# Sertifika bilgilerini görüntüle
http --debug --verify=no GET https://self-signed.example.com 2>&1 | grep -i cert
Production’da --verify=no kullanmaktan kaçının, ama test ve geliştirme ortamlarında self-signed sertifikalarla uğraşırken hayat kurtarıcı.
Gerçek Dünya Senaryosu 3: Elasticsearch API’si ile Çalışmak
Elasticsearch gibi JSON ağırlıklı servislerle çalışırken httpie gerçekten parlıyor:
# Cluster sağlık durumu
http GET localhost:9200/_cluster/health?pretty
# Index oluştur
http PUT localhost:9200/log-2024-01
settings:='{"number_of_shards": 3, "number_of_replicas": 1}'
mappings:='{"properties": {"timestamp": {"type": "date"}, "level": {"type": "keyword"}, "message": {"type": "text"}}}'
# Doküman ekle
http POST localhost:9200/log-2024-01/_doc
timestamp="2024-01-15T14:30:00Z"
level="ERROR"
service="payment-service"
message="Veritabani baglantisi kurulamadi"
host="app-server-03"
# Arama sorgusu
http POST localhost:9200/log-2024-01/_search
query:='{"bool": {"must": [{"term": {"level": "ERROR"}}, {"range": {"timestamp": {"gte": "2024-01-15T00:00:00Z"}}}]}}'
# Index istatistikleri
http GET localhost:9200/log-2024-01/_stats/docs,store
Curl ile aynı Elasticsearch sorgularını yazmayı deneyin, farkı anlarsınız.
Pipe ve Diğer Araçlarla Entegrasyon
# jq ile birlikte kullanım
http GET https://api.example.com/users
"Authorization:Bearer $TOKEN"
--body | jq '.data[] | {id: .id, name: .name, email: .email}'
# Sadece belirli field'ı çek
http GET https://api.example.com/users --body |
jq -r '.data[].email' |
sort > emails.txt
# Response'u başka bir isteğe pipe et
USER_ID=$(http POST https://api.example.com/users
name="Yeni Kullanici"
email="[email protected]"
--body | jq -r '.id')
echo "Oluşturulan kullanıcı ID: $USER_ID"
# İzin ata
http POST https://api.example.com/users/$USER_ID/roles
"Authorization:Bearer $TOKEN"
roles:='["viewer", "reporter"]'
Proxy Kullanımı
Kurumsal ortamlarda proxy arkasında çalışmak kaçınılmaz:
# HTTP proxy
http --proxy=http:http://proxy.sirket.com:8080 GET https://external-api.example.com/
# HTTPS proxy
http --proxy=https:http://proxy.sirket.com:8080 GET https://external-api.example.com/
# Environment variable ile (daha pratik)
export HTTP_PROXY=http://proxy.sirket.com:8080
export HTTPS_PROXY=http://proxy.sirket.com:8080
http GET https://external-api.example.com/
# Proxy bypass (no_proxy)
export NO_PROXY=localhost,127.0.0.1,.internal.sirket.com
Konfigürasyon Dosyası ile Varsayılan Değerler
Sürekli aynı header’ları yazmaktan sıkıldıysanız, default ayarları config dosyasına yazabilirsiniz:
# Config dosyası konumu
cat ~/.config/httpie/config.json
# Örnek config.json içeriği (bash heredoc ile oluşturma)
cat > ~/.config/httpie/config.json << 'EOF'
{
"default_options": [
"--style=monokai",
"--timeout=30",
"--verify=yes"
]
}
EOF
Belirli bir projeye özel config için environment variable kullanabilirsiniz:
export HTTPIE_CONFIG_DIR=~/.config/httpie/myproject
mkdir -p $HTTPIE_CONFIG_DIR
cat > $HTTPIE_CONFIG_DIR/config.json << 'EOF'
{
"default_options": [
"--session=default",
"--timeout=60"
]
}
EOF
Kullanışlı Flag’ler Özeti
–check-status: HTTP hata kodlarında non-zero exit code döndürür, scripting için kritik
–timeout=SANIYE: İstek timeout süresi (varsayılan 0, yani sınırsız)
–follow: 301/302 yönlendirmelerini takip et
–max-redirects=N: Maksimum yönlendirme sayısı
–download / -d: Response’u dosyaya indir
–continue / -c: Yarım kalan indirmeye devam et (–download ile birlikte)
–quiet / -q: Çıktıyı bastır (sadece hata durumunda bir şey yazar)
–print=hHbB: Neyin yazdırılacağını seç (h: istek header, H: yanıt header, b: istek body, B: yanıt body)
–style=STIL: Renk teması (monokai, solarized, autumn, vs.)
–pretty=all/colors/format/none: Çıktı biçimlendirme seviyesi
–stream: Streaming yanıtlar için (Server-Sent Events gibi)
HTTPie vs Curl: Ne Zaman Hangisi?
Bu tartışmayı açmadan geçemezdim. Cevap aslında net: ikisi de lazım.
Curl her sistemde var, script’lerde curl kullanmak daha taşınabilir. Ama günlük API testlerinde, interaktif kullanımda, JSON ağırlıklı REST API’lerini keşfederken httpie çok daha verimli. Özellikle renkli çıktı ve otomatik JSON formatlaması, büyük response’ları okuyrken ciddi fark yaratıyor.
Scripting için curl, interaktif test için httpie diye düşünebilirsiniz. Zamanla her ikisini de refleks olarak kullanmaya başlıyorsunuz.
Sonuç
HTTPie’yi ilk kurduğumda “bu sadece curl’ün süslü versiyonu” diye düşünmüştüm. Yanılmışım. Özellikle oturum yönetimi, offline modu, –check-status ile scripting entegrasyonu ve JSON notasyonu, onu gerçekten ayrı bir araç olarak konumlandırıyor.
Eğer ekibinizde herkes farklı curl one-liner’ları ezberlemiş durumdaysa ve API testleri her seferinde “bu header nasıl yazılıyordu?” sorusuyla başlıyorsa, httpie geçişi yapmanın tam zamanı. Öğrenme eğrisi neredeyse yok, iki üç istek attıktan sonra notasyona alışıyorsunuz.
Elasticsearch, Kubernetes API, GitHub API gibi JSON ağırlıklı servislerle düzenli çalışıyorsanız, httpie iş akışınızın kalıcı bir parçası haline gelecek. Benim oldu en azından.
