簡體   English   中英

如何在 DRF 中強制執行 POST 冪等性?

[英]How to enforce POST idempotency in DRF?

我有一個使用 Django Rest Framework 的 API,我想防止重復的POST請求(本着Post Once Exactly (POE)的精神)。 特別是,我試圖處理的場景是:

  1. 客戶端發送 HTTP POST 以創建對象。
  2. API 后端創建對象並將其提交到數據庫。
  3. 客戶端失去網絡連接。
  4. API 后端嘗試發回成功響應,但由於客戶端丟失網絡而無法這樣做。
  5. 客戶端永遠不會得到“成功”響應,因此假設請求失敗。 客戶端重試請求,創建一個重復的對象。

郵件列表上對此進行了一些討論,但沒有具體化代碼。 人們現在如何解決這個問題?

我通過添加對可由客戶端設置的X-Idempotency-Key http 標頭的支持解決了這個問題。 然后,我使用自定義權限類檢查非冪等請求,該類檢查最近是否已看到冪等鍵(在緩存中):

class IsIdempotent(permissions.BasePermission):
    message = 'Duplicate request detected.'

    def has_permission(self, request, view):
        if request.method != 'POST':
            return True
        ival = request.META.get('HTTP_X_IDEMPOTENCY_KEY')
        if ival is None:
            return True
        ival = ival[:128]
        key = 'idemp-{}-{}'.format(request.user.pk, ival)
        is_idempotent = bool(cache.add(key, 'yes',
                                       settings.IDEMPOTENCY_TIMEOUT))
        if not is_idempotent:
            logger.info(u'Duplicate request (non-idempotent): %s', key)
        return is_idempotent

我可以像這樣添加到我的觀點中:

class MyViewSet(mixins.RetrieveModelMixin,
                mixins.UpdateModelMixin,
                mixins.ListModelMixin,
                viewsets.GenericViewSet):
    permission_classes = [permissions.IsAuthenticated,
                          IsIdempotent]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM