REST API'de Idempotency Key ile Yinelenen İstekleri Engelle
Ödeme işlemi yaptığınızda ağ koptu, istek tekrar gitti, iki kez para çekildi. bu sorunu çözmek için idempotency key kullanılır. API'ye gönderilen her isteğe benzersiz bir tanımlayıcı eklenir; sunucu aynı key'i görmezse isteği yeniden işler, görmezse önceki sonucu döner.
Bu mekanizma özellikle ödeme, para transferi ve kritik veri işlemleri için hayati. Istemci tarafından oluşturulan UUID veya hash, isteğin başlığında gönderilir ve sunucu bunu saklar. Aynı key ile gelen sonraki istekler veritabanına sorgulanmadan önceki cevap döndürülür.
Python ve Flask ile basit bir örnek:
1from flask import Flask, request, jsonify2from uuid import uuid43import json45app = Flask(__name__)67# İstek geçmişini tutmak için (gerçekte Redis veya veritabanı kullan)8request_cache = {}910@app.route('/api/transfer', methods=['POST'])11def transfer():12idempotency_key = request.headers.get('Idempotency-Key')1314if not idempotency_key:15return jsonify({'error': 'Idempotency-Key başlığı gerekli'}), 4001617# Aynı key daha önce işlendiyse sonucu döndür18if idempotency_key in request_cache:19return jsonify(request_cache[idempotency_key]), 2002021# İsteği işle22data = request.get_json()23amount = data.get('amount')2425# Simüle edilmiş işlem26result = {27'status': 'success',28'transaction_id': str(uuid4()),29'amount': amount,30'message': 'Para transferi başarılı'31}3233# Sonucu cache'e kaydet34request_cache[idempotency_key] = result3536return jsonify(result), 2003738if __name__ == '__main__':39app.run(debug=True)İstemci tarafından istek gönderirken:
1import requests2from uuid import uuid434idempotency_key = str(uuid4())56headers = {7'Idempotency-Key': idempotency_key,8'Content-Type': 'application/json'9}1011payload = {'amount': 100}1213# İlk istek14response1 = requests.post('http://localhost:5000/api/transfer', 15json=payload, headers=headers)16print("1. Yanıt:", response1.json())1718# Aynı key ile tekrar istek (sonuç değişmez)19response2 = requests.post('http://localhost:5000/api/transfer', 20json=payload, headers=headers)21print("2. Yanıt:", response2.json())Beklenen çıktı: her iki istekte de aynı `transaction_id` dönecektir.
Gerçek ortamda isteği cache'e kaydedip TTL (time-to-live) belirleyin, örneğin 24 saat sonra otomatik silinsin. Redis veya Memcached kullanmak performansı arttırır. Ayrıca idempotency key'i veritabanında indexleyin, böylece arama hızlı olur. Dikkat: GET, DELETE gibi güvenli işlemlerde key'e gerek yoktur; sadece state değiştirenler (POST, PUT, PATCH) için kullanın.
0 yorum