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:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1from flask import Flask, request, jsonify
2from uuid import uuid4
3import json
4
5app = Flask(__name__)
6
7# İstek geçmişini tutmak için (gerçekte Redis veya veritabanı kullan)
8request_cache = {}
9
10@app.route('/api/transfer', methods=['POST'])
11def transfer():
12idempotency_key = request.headers.get('Idempotency-Key')
13
14if not idempotency_key:
15return jsonify({'error': 'Idempotency-Key başlığı gerekli'}), 400
16
17# Aynı key daha önce işlendiyse sonucu döndür
18if idempotency_key in request_cache:
19return jsonify(request_cache[idempotency_key]), 200
20
21# İsteği işle
22data = request.get_json()
23amount = data.get('amount')
24
25# Simüle edilmiş işlem
26result = {
27'status': 'success',
28'transaction_id': str(uuid4()),
29'amount': amount,
30'message': 'Para transferi başarılı'
31}
32
33# Sonucu cache'e kaydet
34request_cache[idempotency_key] = result
35
36return jsonify(result), 200
37
38if __name__ == '__main__':
39app.run(debug=True)

İstemci tarafından istek gönderirken:

1import requests
2from uuid import uuid4
3
4idempotency_key = str(uuid4())
5
6headers = {
7'Idempotency-Key': idempotency_key,
8'Content-Type': 'application/json'
9}
10
11payload = {'amount': 100}
12
13# İlk istek
14response1 = requests.post('http://localhost:5000/api/transfer',
15json=payload, headers=headers)
16print("1. Yanıt:", response1.json())
17
18# 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.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz