8 मिनट पढ़ें

सशर्त API अनुरोध एजेंट के पुराने overwrite को कैसे रोकते हैं

सशर्त API अनुरोध एजेंट से चलने वाले updates को पुराने overwrite से बचाते हैं। ETags, version fields, If-Match, 412 errors और सुरक्षित retry rules जानें।

सशर्त API अनुरोध एजेंट के पुराने overwrite को कैसे रोकते हैं

एक एजेंट पूरी तरह वैध API अनुरोध बना सकता है और फिर भी वास्तविक नुकसान कर सकता है। समस्या तब आती है जब वह कोई record पढ़ता है, कोई दूसरा actor उसे बदल देता है और एजेंट बाद में अपनी पुरानी copy लिखकर नई स्थिति को मिटा देता है। Authentication इसे नहीं रोकता। Authorization भी नहीं। अनुरोध किसी अधिकृत principal से आया था, लेकिन उसमें वास्तविकता का पुराना snapshot था।

सशर्त API अनुरोध इस खास समस्या को ठीक करते हैं। क्लाइंट मूल रूप से कहता है, «यह बदलाव तभी लागू करें जब resource अभी भी वही version हो जिसे मैंने देखा था।» सर्वर write के हिस्से के रूप में इस बात की जांच करता है। अगर शर्त गलत हो, तो सर्वर कुछ बदलने से पहले कार्रवाई रोक देता है।

Coding agents के मामले में यह contract उस व्यक्ति की तुलना में अधिक जरूरी है जो form पर क्लिक कर रहा हो। एजेंट कई resources पढ़ सकते हैं, code देखने या tests चलाने के लिए रुक सकते हैं और दुनिया बदल जाने के बाद writes का batch भेज सकते हैं। हर महत्वपूर्ण update को read-modify-write operation मानें, जब तक API यह साबित न कर सके कि वह append या commutative command है।

सामान्य read-modify-write flow में lost updates होते हैं

Lost update तब होता है जब दो writers एक ही पुरानी स्थिति से शुरू करते हैं और बाद वाला write पहले वाले बदलाव को मिटा देता है। इसके लिए database outage, malicious user या खराब network जरूरी नहीं है। एक unconditional replacement स्वीकार करने वाला server ही काफी है।

मान लीजिए deployment configuration JSON के रूप में उपलब्ध है:

{
  "name": "billing-worker",
  "replicas": 3,
  "image": "registry.example/billing:2.4.0",
  "maintenanceMode": false
}

एक एजेंट load test से पहले replicas को 3 से 5 करने के लिए इसे पढ़ता है। उसके काम करने के दौरान एक operator queue की समस्या जांचने के लिए maintenanceMode को true कर देता है। अगर एजेंट बाद में अपने saved document के साथ पूरा PUT भेजता है, तो वह maintenanceMode को फिर false कर सकता है। अनुरोध ने replicas को सही तरह बदला, लेकिन उस safety decision को भी पलट दिया जिसे एजेंट ने कभी देखा ही नहीं था।

Partial update नुकसान का दायरा घटाता है, लेकिन race खत्म नहीं करता। अगर एजेंट /replicas को बदलने के लिए PATCH भेजता है, तो पढ़ने के बाद वह field फिर भी बदल सकती है। इससे भी महत्वपूर्ण बात यह है कि replicas को 5 करने का निर्णय दूसरे बदले हुए fields पर निर्भर हो सकता है। PATCH request body का आकार बताता है। यह नहीं बताता कि body resource के किस version पर आधारित है।

इसीलिए «हमारा UI केवल एक field बदलता है» concurrency design नहीं है। UI कुछ समय तक समस्या छिपा सकता है, क्योंकि लोग धीरे काम करते हैं और fresh pages देखते हैं। Autonomous process के पास ऐसे आकस्मिक safeguards नहीं होते।

ETag उस representation की पहचान करता है जिसे क्लाइंट ने देखा

ETag response header एक HTTP validator है। Server जब कोई representation लौटाता है, तो उसके साथ ऐसा token जोड़ सकता है जो उस representation के version की पहचान करे:

HTTP/1.1 200 OK
Content-Type: application/json
ETag: "deploy-8f31c2"

{
  "name": "billing-worker",
  "replicas": 3,
  "image": "registry.example/billing:2.4.0",
  "maintenanceMode": false
}

इस string का कोई अनिवार्य internal format नहीं है। इसमें database revision, content hash या generated opaque value हो सकती है। Clients को इसे opaque मानना चाहिए। Revision number जानने के लिए tag को parse न करें और JSON body से tag न बनाएं। उसका अर्थ server तय करता है।

RFC 9110 entity tags को परिभाषित करता है और strong तथा weak tags में अंतर बताता है। Strong ETag का सामान्य quoted syntax होता है, जैसे "deploy-8f31c2"। इसका अर्थ है कि server की चुनी हुई representation semantics के अनुसार representations byte-for-byte समान हैं। Weak tag W/ से शुरू होता है, जैसे W/"deploy-8f31c2", और केवल इतना बताता है कि दोनों representations cache validation के लिए पर्याप्त रूप से समान हैं।

यह अंतर अक्सर धुंधला हो जाता है। कई GET cache checks के लिए weak validators ठीक हैं। Write को सुरक्षित रखने के लिए वे गलत साधन हैं, क्योंकि दो «काफी समान» representations में ऐसा field अलग हो सकता है जिसे write मिटा देगा। RFC 9110 के अनुसार If-Match में strong comparison होना चाहिए। अगर आपका API केवल weak ETags publish करता है, तो उसने optimistic concurrency के लिए उपयुक्त ETag दिया ही नहीं है।

अलग representations के लिए किसी resource के अलग ETags हो सकते हैं। Pretty-printed JSON, compact JSON या content-negotiated formats में हर एक को अपना validator मिल सकता है। यह HTTP का वैध व्यवहार है, लेकिन API clients के लिए असुविधाजनक है। जब संभव हो, write endpoints के लिए stable canonical representation रखें। तब GET पर मिला ETag PUT, PATCH और DELETE पर भी अर्थपूर्ण रहेगा।

If-Match version check को server की जिम्मेदारी बनाता है

If-Match unsafe request में expected ETag रखता है। Server method तभी चलाता है जब current representation supplied tag से strongly match करे।

एजेंट record पढ़कर मिले header को रख सकता है:

curl -i \\
  -H 'Authorization: Bearer $TOKEN' \\
  https://api.example.test/v1/deployments/billing-worker

Response में यह शामिल होगा:

ETag: "deploy-8f31c2"

इसके बाद वह अपने इच्छित सबसे छोटे बदलाव को पढ़ते समय मिले validator के साथ भेज सकता है:

curl -i -X PATCH \\
  -H 'Authorization: Bearer $TOKEN' \\
  -H 'Content-Type: application/json-patch+json' \\
  -H 'If-Match: "deploy-8f31c2"' \\
  --data '[{"op":"replace","path":"/replicas","value":5}]' \\
  https://api.example.test/v1/deployments/billing-worker

अगर resource उसी version पर है, तो server patch लागू करता है और नया ETag लौटाता है:

HTTP/1.1 200 OK
ETag: "deploy-a19d77"
Content-Type: application/json

{
  "name": "billing-worker",
  "replicas": 5,
  "image": "registry.example/billing:2.4.0",
  "maintenanceMode": false
}

अगर operator के बदलाव से current version पहले ही बदल चुका है, तो server यह लौटाता है:

HTTP/1.1 412 Precondition Failed
Content-Type: application/problem+json

{
  "type": "https://api.example.test/problems/precondition-failed",
  "title": "The deployment changed after it was read",
  "status": 412,
  "detail": "Fetch the current deployment before retrying this update."
}

RFC 9110 कहता है कि जब If-Match condition false हो, तो origin server को requested method नहीं चलाना चाहिए। यही वह सुरक्षा है जिसके लिए आप यह व्यवस्था बना रहे हैं। Check और mutation एक ही atomic operation में होने चाहिए। अगर handler row पढ़ता है, application memory में revision compare करता है और बाद में write करता है, तो comparison और write के बीच race बनी रहती है।

Relational database में implementation अक्सर conditional update जैसा दिखता है:

UPDATE deployments
SET replicas = :replicas,
    revision = revision + 1
WHERE id = :id
  AND revision = :expected_revision;

अगर प्रभावित rows की संख्या शून्य हो, तो API 412 लौटाता है। अगर संख्या एक हो, तो API updated document लौटाता है और नए revision से अगला ETag बनाता है। Test को WHERE clause या equivalent transactional compare-and-set primitive में रखें। इसे दो अलग queries में बांटकर सुरक्षित न मानें।

Version fields application data में यही contract दिखाते हैं

Version field application-level validator है। यह clients को visible revision देता है, जिसे वे request body, query या dedicated header में वापस भेजते हैं। Generated SDKs, message queues या ऐसे protocols के साथ यह आसान हो सकता है जो HTTP response headers को अच्छी तरह preserve नहीं करते।

GET ऐसा response दे सकता है:

{
  "id": "billing-worker",
  "revision": 42,
  "replicas": 3,
  "maintenanceMode": false
}

Update अपनी अपेक्षा साफ तौर पर बता सकता है:

PATCH /v1/deployments/billing-worker HTTP/1.1
Content-Type: application/json

{
  "expectedRevision": 42,
  "replicas": 5
}

Server expectedRevision का stored revision से atomic मिलान करता है। सफलता पर revision बढ़ाता है। Mismatch होने पर documented response के साथ request अस्वीकार करता है, आम तौर पर जब field precondition की तरह काम करे तो 412 लौटाता है।

Version field को timestamp न समझें। Monotonic integer revision equality को स्पष्ट रखता है। Timestamps कई कठिन सवाल खड़े करते हैं: server कितनी precision रखता है? क्या दो writes एक ही precision bucket में आ सकती हैं? Serialization ने value बदली? क्या replica अलग समय assign करती है? इनमें से कुछ समस्याएं हल की जा सकती हैं, लेकिन revision counter को समझाना आसान है।

ETags और version fields एक-दूसरे के विरोधी नहीं हैं। API दोनों दे सकता है, जिसमें ETag standard HTTP semantics रखे और revision application code को बदलाव दिखाने या reconcile करने में मदद करे। दोनों एक ही committed state से आने चाहिए। अगर एक version 42 कहता है और दूसरा गलती से version 41 की ओर इशारा करता है, तो clients के पास सुरक्षित recovery का रास्ता नहीं रहता।

अगर ETag और revision field अलग हो सकते हैं, तो दोनों में से किसी एक को स्वीकार न करें। Route के लिए एक authoritative precondition चुनें या दोनों का मेल जरूरी करें। Flexible input contracts तब तक अच्छे लगते हैं जब तक कोई client stale body revision और fresh copied header साथ न भेज दे और किसी को पता न हो कि server ने किस claim को माना।

If-None-Match creation को सुरक्षित करता है, stale replacement को नहीं

राइट करने वाले प्रोसेस की पहचान करें
नए एजेंट प्रोसेस की पहली कॉल मंजूरी के लिए उसकी code-signing authority दिखाती है।

If-None-Match predicate को उलट देता है। इसका अर्थ है कि method तभी आगे बढ़े जब current representation supplied tags में से किसी से match न करे। Unsafe methods के लिए false condition पर 412 मिलता है।

इसका सबसे उपयोगी mutation form If-None-Match: * है, जिसका अर्थ है, «इसे तभी बनाएं जब अभी कोई current representation मौजूद न हो।» Client named resource creation सुरक्षित तरीके से आजमा सकता है:

curl -i -X PUT \\
  -H 'Authorization: Bearer $TOKEN' \\
  -H 'Content-Type: application/json' \\
  -H 'If-None-Match: *' \\
  --data '{"name":"nightly-export","schedule":"0 2 * * *"}' \\
  https://api.example.test/v1/jobs/nightly-export

अगर किसी दूसरे client ने वह job पहले ही बना दी है, तो server उसे चुपचाप replace करने के बजाय request अस्वीकार करता है। यह तब उपयोगी है जब एजेंट ने identifier बनाया हो और उसी नाम वाले existing object पर कब्जा न करना हो।

सामान्य optimistic concurrency के लिए If-Match: * न भेजें। यह केवल इतना मांगता है कि कोई current representation मौजूद हो। इससे एजेंट को किसी भी current version को overwrite करने की अनुमति मिल जाती है, जिसमें वह version भी शामिल है जिसे उसने कभी पढ़ा नहीं। यह existence protection है, lost-update protection नहीं।

GET और HEAD के लिए If-None-Match caching को support करता है। Matching tag पर आम तौर पर 304 Not Modified मिलता है और response body नहीं होती। Developers अक्सर ETags से इसी cache behavior के कारण परिचित होते हैं। इसे देखकर validators को केवल cache plumbing न समझें। Writes पर इसी mechanism के परिणाम कहीं अधिक गंभीर हो सकते हैं।

Stale-write response के बाद एजेंट के लिए स्पष्ट policy जरूरी है

412 को current mutation plan रोक देना चाहिए। एजेंट की पुरानी धारणा गलत साबित हो चुकी है, और वही request दोबारा भेजने से वह सही नहीं हो जाएगी।

सुरक्षित recovery sequence छोटा है:

  1. Current representation और उसका नया validator प्राप्त करें।
  2. केवल patch में नामित field नहीं, बल्कि इच्छित action के पीछे की fields और state assumptions की तुलना करें।
  3. नए validator के साथ तभी retry करें जब intent बिना किसी नए अर्थ-निर्धारण के अभी भी सही हो।
  4. जब current state action का अर्थ, दायरा या जोखिम बदल दे, तो मंजूरी मांगें या रुक जाएं।

दूसरा कदम वह जगह है जहां automated clients अक्सर shortcut लेते हैं। मान लीजिए एजेंट membership list पढ़ने के बाद किसी user को access group से हटाने की योजना बनाता है। फिर कोई व्यक्ति उस user की role को contractor से incident responder में बदल देता है। दोबारा fetch करने के बाद एजेंट अब भी syntactically legal removal कर सकता है। फिर भी उसे अपने-आप ऐसा नहीं करना चाहिए, क्योंकि role बदलने से मूल योजना संदिग्ध हो गई है।

Work record छोटा लेकिन पूरा रखें: resource URI, observed ETag या revision, पढ़ी गई fields, इच्छित mutation और response। Tool runner इसे छोटे task के दौरान memory में रख सकता है। लंबे autonomous workflow को इसे अपने audited task state में persist करना चाहिए। Model से केवल prose के आधार पर validator याद रखने को कभी न कहें। Quoted header values आसानी से छूट, बदल या गलत resource पर दोबारा इस्तेमाल हो सकती हैं।

Sallyport HTTP call चलाते समय एजेंट को API credential से दूर रख सकता है, लेकिन एजेंट को ETag को सामान्य request data की तरह सुरक्षित रखना और भेजना फिर भी जरूरी है। Credential isolation और concurrency control अलग-अलग failures को संबोधित करते हैं, इसलिए महत्वपूर्ण actions पर दोनों का इस्तेमाल करें।

412, 409 और 428 अलग failures बताते हैं

जब client ने conditional request header या equivalent documented precondition दी हो और वह condition false हो, तो 412 Precondition Failed लौटाएं। Response सटीक रूप से बताता है कि resource अब उस state में नहीं है जिसका client ने दावा किया था।

जब server किसी route के लिए precondition जरूरी मानता हो और client ने उसे छोड़ा हो, तो 428 Precondition Required लौटाएं। RFC 6585 ने lost updates रोकने के लिए यह status खास तौर पर परिभाषित किया है। Response कह सकता है कि PATCH के लिए If-Match जरूरी है और, अगर उसे उजागर करने में disclosure risk न हो, current ETag भी दे सकता है।

जब version condition पास होने के बाद भी request application state से conflict करे, तो 409 Conflict लौटाएं। उदाहरण के लिए client का If-Match current invoice से match कर सकता है, फिर भी server cancellation रोक सकता है क्योंकि payment settlement शुरू हो चुका है। Version test पास हुआ, लेकिन business command invoice state से conflict करता है।

इन सबको एक generic error में न मिलाएं। Agent की प्रतिक्रिया अलग होनी चाहिए:

  • 428 के बाद resource प्राप्त करें और आवश्यक condition के साथ retry करें।
  • 412 के बाद दोबारा fetch करें और मूल intent का फिर आकलन करें।
  • 409 के बाद domain conflict देखें और API के business resolution path का पालन करें।

उपयोगी error body resource का नाम दे, failed condition की पहचान करे लेकिन secrets दोहराए नहीं, और बताए कि fresh GET मदद कर सकता है या नहीं। उसे retry को harmless नहीं दिखाना चाहिए। HTTP status machine-readable category देता है, जबकि body operator को अगला कदम तय करने के लिए पर्याप्त context देती है।

Last-modified dates compatibility fallback हैं

सुरक्षित अनुरोध चलाएं
Sallyport खुद HTTP अनुरोध चलाता है और क्रेडेंशियल उजागर किए बिना परिणाम लौटाता है।

Last-Modified और If-Unmodified-Since इससे जुड़ी condition व्यक्त कर सकते हैं: method तभी चलाएं जब supplied date के बाद resource बदला न हो। जहां पुराना API modification times पहले से publish करता हो और tags जोड़ने में समय लगे, वहां ये उपयोगी रहते हैं।

महत्वपूर्ण writes के लिए ये कमजोर हैं। HTTP dates में one-second precision होती है। एक ही second में हुए दो बदलाव एक ही visible date दे सकते हैं, और client को पता नहीं हो सकता कि server का stored timestamp header से अधिक precision रखता है या नहीं। Replication, clocks और serialization भी अप्रत्याशित परिणाम ला सकते हैं।

अगर client If-Match और If-Unmodified-Since दोनों भेजता है, तो RFC 9110 के अनुसार If-Match को प्राथमिकता मिलती है। यह उचित है। Strong validator exact version test देता है, जबकि date एक approximation है।

जब तक standard headers किसी protocol requirement को पूरा न कर पाएं, अपना X-If-Version header न बनाएं। Custom headers SDKs और proxies में तेजी से फैलते हैं और फिर स्थायी compatibility work बन जाते हैं। ETag और If-Match के semantics स्पष्ट हैं, status codes ज्ञात हैं और सामान्य HTTP tooling में इनका support है।

PATCH formats को भी अलग tests चाहिए

Conditional headers resource के version की रक्षा करते हैं। वे यह validate नहीं करते कि patch सुरक्षित transformation व्यक्त करता है या नहीं। सही ETag होने पर भी ऐसा JSON Merge Patch जिसमें पूरा nested object शामिल हो, sibling fields मिटा सकता है। JSON Patch गलत array position को target कर सकता है, अगर API ऐसी ordered list model करता हो जिसकी membership बदल चुकी हो।

Operation के अनुरूप patch format चुनें। RFC 6902 में परिभाषित JSON Patch replace, add, remove और test जैसे operations को specific paths पर व्यक्त करता है। उसका test operation document के भीतर किसी value की जांच कर सकता है, फिर बाद के operations चल सकते हैं। RFC 7396 में परिभाषित JSON Merge Patch desired partial document बताता है और null को deletion मानता है।

Document-level ETag को बाहरी guard बनाए रखें। जब operation में कोई field-specific assumption स्पष्ट करना उपयोगी हो, तब JSON Patch test जोड़ें:

[
  {"op":"test","path":"/maintenanceMode","value":false},
  {"op":"replace","path":"/replicas","value":5}
]

अगर इस request से पहले किसी दूसरे writer ने maintenanceMode बदल दिया, तो request fail होनी चाहिए, ताकि maintenance के दौरान capacity न बढ़े। API को failed JSON Patch test के लिए लौटाए जाने वाले error को document करना चाहिए। कई implementations 409 का इस्तेमाल करते हैं, क्योंकि patch instruction current document से conflict करती है, जबकि बाहरी ETag mismatch 412 रहता है। यह अंतर तब उपयोगी है जब clients को जानना हो कि document पुराना था या state-dependent request ही गलत थी।

General concurrency scheme के रूप में केवल patch test पर निर्भर न रहें। यह केवल उन्हीं paths की रक्षा करता है जिन्हें आपने test करना याद रखा। Strong ETag उस representation version की रक्षा करता है जिस पर एजेंट ने वास्तव में अपनी योजना आधारित की थी।

Servers को write boundary पर precondition लागू करनी चाहिए

महत्वपूर्ण रीट्राई को मंजूरी दें
एजेंट के If-Match अनुरोध भेजने से पहले हर राइट क्रेडेंशियल के लिए कॉल-स्तरीय मंजूरी तय करें।

जो API केवल If-Match की सलाह देता है, वह deadline pressure में विफल होगा। एक client इसे छोड़ देगा, दूसरा SDK इसे forward करना भूल जाएगा और vulnerable endpoint वही बन जाएगा जिसे agents examples के जरिए खोज लेंगे। जहां stale overwrite की महत्वपूर्ण कीमत हो, वहां updates के लिए इसे अनिवार्य करें।

Side effects करने से पहले handler को missing conditions अस्वीकार करनी चाहिए। फिर उसे expected validator को उस storage operation में भेजना चाहिए जो state बदलता है। अगर resource कई tables या external control plane पर आधारित है, तो comparison और state change को एक transaction में रखें या provider का compare-and-set operation इस्तेमाल करें। अगर provider ऐसा नहीं कर सकता, तो आपका API उस write के लिए lost-update protection का ईमानदार वादा नहीं कर सकता।

Race को जानबूझकर test करें। Resource को revision 7 पर रखें। Client A और client B दोनों से GET कराएं। A को If-Match: "7" के साथ PATCH करने दें और verify करें कि उसे revision 8 मिले। फिर B को If-Match: "7" के साथ PATCH करने दें और verify करें कि उसे 412 मिले तथा उसका इच्छित बदलाव दिखाई न दे। DELETE, full PUT और किसी भी ऐसे bulk action के साथ भी दोहराएं जो prior read के आधार पर resource लिखता है।

खतरनाक shortcuts भी test करें: protected routes पर missing If-Match को 428 मिलना चाहिए, If-Match: * को stale-write protection के रूप में प्रस्तुत नहीं करना चाहिए और weak ETag को strong comparison में पास नहीं होना चाहिए। ये tests उन regressions को पकड़ते हैं जो नया endpoint सामान्य repository method को bypass करने पर आते हैं।

सुरक्षित रास्ते को overwrite से आसान बनाएं

API को mutable resources के हर GET पर ETags लौटाने चाहिए, हर unsafe operation के पास required conditions document करनी चाहिए और SDK methods को validators स्वाभाविक रूप से carry करना चाहिए। दूसरे writer का काम नुकसान से बचाने के लिए client को किसी obscure response object से raw headers निकालने की जरूरत नहीं होनी चाहिए।

Agents के लिए planning और execution अलग रखें। Target पढ़ें, उसका validator record करें, intended mutation लिखें और conditional call चलाएं। अगर कोई observation बदलती है, तो planned write छोड़ दें, जब तक एजेंट यह न दिखा सके कि बदलाव irrelevant है। यह नियम conservative लगता है, क्योंकि यह सचमुच conservative है। विकल्प automated process को उन facts के आधार पर कार्रवाई की authority देना है जिन्हें वह पुराना जानता है।

उन endpoints से शुरुआत करें जहां overwritten change किसी को तुरंत जगा देगा: deployment settings, access control, customer records, payment state और secrets metadata। If-Match जोड़ें, missing precondition को fail करें और route पर दो writers का test करें। जब server default रूप से stale writes रोकने लगेगा, तो agent की speed ordinary concurrency को silent damage में नहीं बदलेगी।

सामान्य प्रश्न

API में ETag क्या होता है?

ETag एक HTTP validator है जो किसी संसाधन के खास representation की पहचान करता है। जब क्लाइंट केवल उसी संस्करण को अपडेट या डिलीट करना चाहता है जिसे उसने पहले पढ़ा था, तो वह यह मान If-Match में वापस भेजता है। मौजूदा ETag अलग होने पर सर्वर को राइट अस्वीकार करना चाहिए।

API को If-Match का इस्तेमाल कब करना चाहिए?

किसी अपडेट, replacement, deletion या ऐसी दूसरी कार्रवाई के लिए If-Match इस्तेमाल करें जो केवल उसी संस्करण पर लागू हो जिसे क्लाइंट ने जांचा है। मेल खाने वाला tag method को अनुमति देता है, जबकि अलग tag पर 412 Precondition Failed मिलना चाहिए। यह पुराने क्लाइंट को राइट रेस में चुपचाप जीतने से रोकने का standard तरीका है।

If-Match और If-None-Match में क्या अंतर है?

If-Match optimistic concurrency के लिए है, जबकि If-None-Match आम तौर पर creation रोकने या अपरिवर्तित representation को दोबारा भेजने से बचने के लिए इस्तेमाल होता है। Unsafe request में If-None-Match: * का अर्थ है, «इसे तभी करें जब कोई मौजूदा resource न हो।» इसे read-modify-write guard के विकल्प के रूप में इस्तेमाल न करें।

412 response मिलने के बाद एजेंट को क्या करना चाहिए?

412 Precondition Failed का अर्थ है कि अनुरोध की HTTP condition false थी। क्लाइंट को मौजूदा representation फिर से प्राप्त करनी चाहिए, उसे अपने इच्छित बदलाव से मिलाना चाहिए और तय करना चाहिए कि दोबारा कोशिश करनी है, बदलाव मिलाना है या किसी व्यक्ति से पूछना है। वही पुराना अनुरोध दोहराने से केवल वही failure फिर होगा।

क्या मैं ETag की जगह version field इस्तेमाल कर सकता हूं?

Version field काम कर सकता है, बशर्ते सर्वर राइट के दौरान stored revision से उसका atomic मिलान करे। डेवलपर्स के लिए इसे opaque ETag की तुलना में देखना और समझना अक्सर आसान होता है। फिर भी generic clients और caches के लिए standard HTTP conditional semantics चाहिए हों, तो यह ETag का विकल्प नहीं है।

क्या concurrency control के लिए If-Unmodified-Since सुरक्षित है?

आम तौर पर नहीं। If-Unmodified-Since timestamps पर निर्भर करता है, और timestamps की precision सीमित हो सकती है या clock से जुड़ी समस्याएं आ सकती हैं। यह पुराने सिस्टम के साथ compatibility के लिए उपयोगी fallback है, लेकिन महत्वपूर्ण writes के लिए strong ETag या atomic version field अधिक सुरक्षित जांच देता है।

Stale update के लिए API को 409 या 412 लौटाना चाहिए?

409 Conflict business या state conflict बताता है जिसे क्लाइंट को समझना होगा, जैसे unpaid invoice होने पर account बंद करने की कोशिश। 412 Precondition Failed बताता है कि कोई स्पष्ट HTTP precondition false थी। दोनों अलग failures हों तो दोनों status का इस्तेमाल करें, हर अस्वीकृत write को 409 न बनाएं।

क्या If-Match star lost updates को रोकता है?

If-Match: * का अर्थ है कि कोई भी मौजूदा representation स्वीकार्य है। यह केवल उस resource को अपडेट करने से बचाता है जो मौजूद नहीं है। यह नए version को overwrite करने से नहीं रोकता। जब क्लाइंट को दूसरे writer के बदलाव सुरक्षित रखने हों, तो exact ETag value भेजें।

क्या हर PATCH endpoint को ETag जरूरी करना चाहिए?

उन endpoints पर precondition जरूरी करें जहां stale write से पैसे, permissions, deployment state, customer data या configuration बदल सकती है। अगर क्लाइंट आवश्यक condition छोड़ दे, तो server 428 Precondition Required लौटा सकता है। Append-only commands पर इसे बिना वजह लागू न करें, क्योंकि उनमें read-modify-write race नहीं होती।

AI agent को API versions सुरक्षित तरीके से कैसे रखने चाहिए?

एजेंट को ETag या revision को उसी representation से जोड़कर रखना चाहिए जिसे उसने वास्तव में पढ़ा था, अगली protected write में भेजना चाहिए और condition fail होने के बाद उसे छोड़ देना चाहिए। उसे tag गढ़ना, किसी दूसरे resource का tag दोबारा इस्तेमाल करना या semantic conflict को current state overwrite करके अपने-आप हल करना नहीं चाहिए। Resource URL, observed validator, इच्छित fields और response वाला छोटा work record पर्याप्त है।

Sallyport

Sallyport आपके AI एजेंट के लिए API कॉल और SSH कमांड चलाता है। कुंजियाँ आपके Mac पर एक लोकल वॉल्ट में रहती हैं; आप हर रन को स्वीकृत करते हैं और हर क्रिया एक सीलबंद जर्नल में दर्ज होती है।

© 2026 Sallyport · Apache-2.0 के तहत ओपन सोर्स · Oleg Sotnikov