2025, Sep 24 07:32
FastAPI और Vercel में ट्रेलिंग स्लैश से होने वाली रूटिंग समस्याएँ और स्थिर समाधान
FastAPI रूट्स Vercel पर ट्रेलिंग स्लैश से 404, 500 या रीडायरेक्ट लूप दे रहे हैं? RedirectSlashes बंद कर दोनों पाथ वेरिएंट सर्व करने की व्यावहारिक गाइड और कोड देखें.
लोकल वातावरण में FastAPI की रूट्स एक तरह से काम करती हैं, लेकिन Vercel पर उनका व्यवहार अलग हो सकता है। यदि आपके एंडपॉइंट्स कभी-कभी ट्रेलिंग स्लैश पर निर्भर होकर फेल हो रहे हैं, तो संभव है कि आप रीडायरेक्ट नॉर्मलाइज़ेशन के मिसमैच से जूझ रहे हों। लोकली, FastAPI स्लैश के मामले में उदार है; वहीं Vercel पर edge/proxy स्टैक उन्हें अलग ढंग से हैंडल करता है और लूप, 404, या 500 जैसी त्रुटियाँ पैदा कर सकता है। यहाँ दोनों वातावरणों में API को स्थिर रखने का व्यावहारिक तरीका दिया गया है।
समस्या को दोहराने वाला न्यूनतम उदाहरण
नीचे दिया गया रूट /users प्रीफिक्स वाले राउटर के तहत है। लोकल रूप से यह ट्रेलिंग स्लैश हो या न हो—दोनों स्थितियों में ठीक काम करता है, क्योंकि FastAPI डिफॉल्ट रूप से रीडायरेक्ट करता है।
from fastapi import APIRouter, Depends
from ..schemas.user import UserView
from ..auth import ensure_admin
from ..repositories.users import fetch_user_list
users_api = APIRouter(prefix="/users", tags=["users"]) 
@users_api.get("/", response_model=list[UserView])
def fetch_users(_: UserView = Depends(ensure_admin)):
    return fetch_user_list()
Uvicorn के साथ लोकल डेवलपमेंट में, /api/users पर अनुरोध /api/users/ (307) पर रीडायरेक्ट होता है और रूट मैच हो जाता है। लेकिन Vercel पर /api/users/ कॉल करने पर 500 आ सकता है, जबकि /api/users पर 404 या net::ERR_TOO_MANY_REDIRECTS मिल सकता है। डेकोरेटर को खाली पाथ पर बदलना, जैसे @get(""), स्थिति उलट देता है: Vercel चलने लगता है, पर लोकल रिक्वेस्ट्स 404 देने लगती हैं।
वास्तव में हो क्या रहा है
यह ट्रेलिंग-स्लैश नॉर्मलाइज़ेशन का मिसमैच है। FastAPI (Starlette के जरिए) डिफॉल्ट रूप से RedirectSlashes सक्षम रखता है। लोकली, इसका मतलब है कि /api/users अपने आप /api/users/ पर रीडायरेक्ट हो जाता है, जो @get("/") रूट से मेल खा जाता है। Vercel पर edge/proxy लेयर ऐप तक पहुँचने से पहले ट्रेलिंग स्लैश को नॉर्मलाइज़ या स्ट्रिप कर सकती है, और ऑटोमैटिक रीडायरेक्ट या तो स्ट्रिप हो जाता है, लूप में फँस जाता है, या वैसा हैंडल नहीं होता। नतीजा यह कि वहाँ सिर्फ "" पर परिभाषित रूट भरोसेमंद रहता है, जबकि लोकल में उम्मीद की जाती है कि रीडायरेक्ट "/" पर पहुँचे।
यहाँ प्रॉक्सी शामिल हैं: डेवलपमेंट में Next.js /api/:path* को FastAPI तक फॉरवर्ड करता है, और प्रोडक्शन में Vercel /api/(.*) → /api/index.py पर रूट करता है। ये लेयर्स आपकी FastAPI ऐप तक पहुँचने से पहले स्लैश को कैसे संरक्षित या रीडायरेक्ट किया जाए, इस पर असर डालती हैं।
हर वातावरण में काम करने वाला समाधान
स्थिर तरीका यह है कि RedirectSlashes पर निर्भर रहना बंद करें और पाथ के दोनों रूपों को स्पष्ट तौर पर सर्व करें। पहले, अपनी FastAPI एप्लीकेशन में ऑटोमैटिक रीडायरेक्ट अक्षम करें। फिर, एक ही फ़ंक्शन के लिए दो हैंडलर एक्सपोज़ करें: एक खाली पाथ के लिए और एक ट्रेलिंग स्लैश वाले पाथ के लिए। इस तरह /api/users और /api/users/ दोनों सीधे आपके कोड तक पहुँचेंगे, किसी रीडायरेक्ट की ज़रूरत नहीं पड़ेगी।
# main/index.py
from fastapi import FastAPI
core_app = FastAPI(title=config.APP_TITLE, lifespan=app_lifespan, redirect_slashes=False)
# routes/users.py
from fastapi import APIRouter, Depends
from ..schemas.user import UserView
from ..auth import ensure_admin
from ..repositories.users import fetch_user_list
users_api = APIRouter(prefix="/users", tags=["users"]) 
@users_api.get("", include_in_schema=False, response_model=list[UserView])  # /api/users
@users_api.get("/", response_model=list[UserView])                          # /api/users/
def fetch_users(_: UserView = Depends(ensure_admin)):
    return fetch_user_list()
यह डुअल-डेकोरेटर पैटर्न अस्पष्टता हटाता है और किसी भी स्लैश-आधारित रीडायरेक्ट पर निर्भरता खत्म करता है, जिसे Vercel अलग तरह से ट्रीट कर सकता है। include_in_schema=False फ्लैग OpenAPI UI को साफ रखता है—स्कीमा में सिर्फ एक कैनॉनिकल पाथ दिखेगा, जबकि दोनों पर रिक्वेस्ट स्वीकार होंगी।
यह क्यों मायने रखता है
प्रॉक्सी और CDN के पीछे चलने वाली APIs में पाथ नॉर्मलाइज़ेशन की सूक्ष्म भिन्नताएँ अक्सर सामने आती हैं। जब edge नेटवर्क पहले ही रिक्वेस्ट पाथ को सरल या री-राइट कर दे, तो फ्रेमवर्क-लेयर के रीडायरेक्ट्स पर भरोसा करना नाज़ुक साबित हो सकता है। रीडायरेक्ट हटाकर URL के दोनों रूपों को स्पष्ट रूप से हैंडल करना सुनिश्चित करता है कि आपके एंडपॉइंट्स लोकल डेवलपमेंट, सर्वरलेस वातावरण और मल्टी-हॉप प्रॉक्सी के बीच भी पहुँच में बने रहें। इससे 404 और रीडायरेक्ट लूप जैसे परेशान करने वाले फेल्योर भी टलते हैं, जिन्हें दोहराना मुश्किल होता है।
निष्कर्ष
यदि कोई एंडपॉइंट लोकली काम करता है लेकिन Vercel पर ट्रेलिंग स्लैश के आधार पर फेल होता है, तो RedirectSlashes को अक्षम करें और स्लैश व बिना स्लैश—दोनों वेरिएंट्स को एक ही हैंडलर पर मैप करें। स्कीमा में एक को दस्तावेज़ित रखें और दूसरे को छुपाएँ। यह छोटा बदलाव विभिन्न वातावरणों में रीडायरेक्ट से जुड़ी अस्पष्टता दूर करता है और बिना वातावरण-आधारित टॉगल के आपकी FastAPI + Next.js डिप्लॉयमेंट को Vercel पर स्थिर बनाता है।
यह लेख StackOverflow पर एक प्रश्न (लेखक: AmericaDoodles) और AmericaDoodles के उत्तर पर आधारित है।