OpenAPI
OpenAPI स्पेक जोड़ें और नेटिव API संदर्भ प्राप्त करें — प्रत्येक ऑपरेशन के लिए एक वास्तविक पेज, आपके साइडबार और खोज में।
Blume को किसी OpenAPI स्पेक की ओर इंगित करें और यह एक नेटिव API संदर्भ जनरेट करता है: प्रत्येक ऑपरेशन के लिए एक वास्तविक पेज। ये पेज टैब-स्कोप्ड साइडबार में टैग के अनुसार समूहित होते हैं। इनमें स्कीमा तालिकाएँ, अनुरोध/प्रतिक्रिया उदाहरण, जनरेट किए गए कोड नमूने और एक इंटरैक्टिव Try it पैनल भी होता है। चूँकि प्रत्येक ऑपरेशन एक वास्तविक Blume पेज है, इसलिए इसे अपना स्वयं का URL मिलता है, यह साइट खोज और llms.txt में दिखाई देता है, और इसे एक Open Graph इमेज मिलती है — बिल्कुल किसी भी हाथ से लिखे गए दस्तावेज़ की तरह।
प्रत्येक संदर्भ एक एडैप्टर है जिसे blume/reference से इम्पोर्ट किया जाता है और reference के अंतर्गत सूचीबद्ध किया जाता है: OpenAPI दस्तावेज़ के लिए openapi(), AsyncAPI दस्तावेज़ के लिए asyncapi(), और GraphQL स्कीमा के लिए graphql()। प्रत्येक एडैप्टर अपने स्पेक स्रोत, अपना माउंट रूट और अपने डिस्प्ले विकल्प स्वयं सँभालता है, इसलिए सूची में आप प्रत्येक प्रकार के जितने चाहें उतने एडैप्टर रख सकते हैं। नीचे दिया गया कॉन्फ़िग उदाहरण के तौर पर Blume को सार्वजनिक Petstore स्पेक की ओर इंगित करता है।
import { defineConfig } from "blume";
import { openapi } from "blume/reference";
export default defineConfig({
reference: [
openapi({ spec: "https://petstore3.swagger.io/api/v3/openapi.json" }),
],
});
यह संदर्भ को /reference (एक अवलोकन पेज) पर माउंट करता है, और प्रत्येक ऑपरेशन /reference/<tag>/<operation> पर होता है। spec या तो एक http(s) URL होता है या आपके प्रोजेक्ट में किसी स्थानीय फ़ाइल का पाथ। Blume इसे Scalar के OpenAPI पार्सर से पार्स करता है — Swagger 2.0 और OpenAPI 3.0 स्पेक स्वचालित रूप से 3.1 में अपग्रेड हो जाते हैं। एडैप्टर संदर्भ का केवल एक सादा विवरण है, पार्स किया हुआ स्पेक नहीं। इसलिए Blume इसे पहले ही सत्यापित कर सकता है और जनरेट की गई साइट में इनलाइन कर सकता है। यदि आप reference को छोड़ देते हैं (या खाली रखते हैं), तो कोई भी संदर्भ रेंडर नहीं होता। क्या आप इसके बजाय किसी इवेंट-ड्रिवन या GraphQL API का दस्तावेज़ीकरण कर रहे हैं? AsyncAPI और GraphQL देखें।
संदर्भ अपने आप कोई हेडर टैब नहीं जोड़ता। इसे दिखाने के लिए, किसी नेविगेशन टैब को इसके रूट की ओर इंगित करें — इससे नेटिव रेंडरर के लिए ऑपरेशन साइडबार का दायरा भी निर्धारित हो जाता है:
navigation: {
tabs: [{ label: "API", path: "/reference" }],
}
एक स्थानीय स्पेक
सापेक्ष पाथ आपके प्रोजेक्ट रूट से रिज़ॉल्व किया जाता है और बिल्ड के समय पढ़ा जाता है। JSON और YAML दोनों काम करते हैं:
reference: [openapi({ spec: "./openapi.yaml" })],
रूट
route यह नियंत्रित करता है कि संदर्भ कहाँ माउंट होगा। यह अवलोकन पेज का पाथ और प्रत्येक ऑपरेशन रूट का प्रीफ़िक्स तय करता है। नेविगेशन टैब को भी आप इसी रूट की ओर इंगित करते हैं:
reference: [
openapi({
route: "/api", // overview at /api, operations at /api/<tag>/<operation>
spec: "./openapi.yaml",
}),
],
कोड नमूने और स्कीमा
codeSamples यह तय करता है कि प्रत्येक ऑपरेशन के लिए किन भाषाओं के नमूने रेंडर हों (अंतर्निहित: curl, js, python)। expandSchemas नेस्टेड स्कीमा पंक्तियों को संक्षिप्त (collapsed) के बजाय विस्तारित अवस्था में दिखाता है:
reference: [
openapi({
spec: "./openapi.yaml",
codeSamples: ["curl", "js"],
expandSchemas: true,
}),
],
Try it प्लेग्राउंड
नेटिव रूप से रेंडर किए गए ऑपरेशन पेजों में डिफ़ॉल्ट रूप से एक इंटरैक्टिव Try it पैनल शामिल होता है। Blume यह फ़ॉर्म स्वयं ऑपरेशन से जनरेट करता है। इसमें प्रत्येक पाथ, क्वेरी और हेडर पैरामीटर के लिए एक इनपुट और अनुरोध-बॉडी स्कीमा से बना एक बॉडी एडिटर होता है। सब कुछ स्पेक के उदाहरणों से पहले से भरा रहता है। एक सर्वर पिकर स्पेक के servers को सूचीबद्ध करता है, और किसी अन्य बेस URL के लिए एक मुक्त-पाठ फ़ील्ड भी देता है। ऑथ इनपुट ऑपरेशन की रिज़ॉल्व की गई सुरक्षा से मेल खाते हैं: बेयरर टोकन, API कुंजी और बेसिक क्रेडेंशियल। OAuth2 के लिए एक टोकन पेस्ट फ़ील्ड होता है (एक्सेस टोकन आपको स्वयं लाना होगा; Blume यह फ़्लो नहीं चलाता)।
पैनल और कोड नमूने हमेशा एक-दूसरे से मेल खाते हैं। फ़ॉर्म में टाइप किए गए मान जनरेट किए गए नमूनों को तुरंत अपडेट कर देते हैं, इसलिए कॉपी की गई curl कमांड ठीक वही अनुरोध करती है जो Send करेगा। यह पैनल पेज पर बोझ भी नहीं बनता। यह सर्वर पर संक्षिप्त (collapsed) अवस्था में रेंडर होता है, और इसका JavaScript केवल तभी लोड होता है जब कोई पाठक इसे पहली बार खोलता है। जो पाठक इसे कभी नहीं खोलते, उन्हें इसका कोई भी हिस्सा डाउनलोड नहीं करना पड़ता।
इसे पूरी तरह बंद करने के लिए केवल playground: false पर्याप्त है:
reference: [openapi({ spec: "./openapi.yaml", playground: false })],
क्रेडेंशियल
ऑथ इनपुट में टाइप किए गए क्रेडेंशियल केवल मेमोरी में रहते हैं और पेज रीलोड होने पर मिट जाते हैं। Remember on this device चुनने पर वे localStorage में सहेजे जाते हैं, और यह भंडारण docs ओरिजिन तक सीमित रहता है। इन्हें कॉल किए जा रहे API के अलावा कहीं और नहीं भेजा जाता। आप कुछ भी टाइप करें, कोड नमूनों में प्लेसहोल्डर (YOUR_TOKEN आदि) ही दिखते रहते हैं, जब तक कि पाठक Include my values in samples चालू न करे।
CORS और प्रॉक्सी
Scalar एम्बेड की तरह ही, अनुरोध सीधे ब्राउज़र से लक्ष्य API तक जाते हैं। इसलिए API को docs साइट से आने वाले क्रॉस-ओरिजिन अनुरोधों की अनुमति देनी होगी (Access-Control-Allow-Origin)। जो API यह अनुमति नहीं दे सकते, उनके लिए playground.proxy सेट करें। इसमें URL देने पर अनुरोध आपके द्वारा होस्ट किए गए प्रॉक्सी से होकर जाते हैं। true देने पर अंतर्निहित /_api-proxy रूट सक्षम होता है। इसके लिए सर्वर आउटपुट आवश्यक है, यानी एक होस्ट एडैप्टर, जैसे blume/deploy से deployment: vercel():
reference: [
openapi({
spec: "./openapi.yaml",
playground: {
proxy: true, // or a URL of your own
},
}),
],
अंतर्निहित प्रॉक्सी अनुरोधों को केवल उन्हीं ओरिजिन तक भेजता है जिन्हें आपके स्पेक servers में घोषित करते हैं, और यह नियम रीडायरेक्ट पर भी लागू होता है। इससे किसी सार्वजनिक docs डिप्लॉयमेंट का उपयोग उसके नेटवर्क के अन्य होस्ट तक पहुँचने के लिए नहीं किया जा सकता। पैनल में टाइप किया गया Custom base URL प्रलेखित सर्वर नहीं माना जाता, इसलिए प्रॉक्सी सक्षम होने पर उस पर भेजे गए अनुरोध 403 के साथ अस्वीकार कर दिए जाते हैं। प्रॉक्सी अनुरोध बॉडी को केवल 4 MB तक पढ़ता है; इससे बड़े अनुरोध को 413 मिलता है। यह जो भी प्रतिक्रिया आगे भेजता है, उसमें Content-Security-Policy: sandbox, X-Content-Type-Options: nosniff और Cross-Origin-Resource-Policy: same-origin हेडर होते हैं। HTML या SVG प्रतिक्रियाओं में Content-Disposition: attachment भी जुड़ता है। इस तरह, अपना इनपुट वापस दिखाने वाला कोई API त्रुटि पेज docs ओरिजिन पर स्क्रिप्ट नहीं चला सकता।
एकाधिक स्पेक
एक ही एडैप्टर से एक से अधिक स्पेक प्रकाशित करने के लिए sources का उपयोग करें। प्रत्येक स्रोत को अपना अवलोकन रूट और ऑपरेशन पेज मिलते हैं, जबकि डिस्प्ले विकल्प एडैप्टर से साझा होते हैं। प्रत्येक स्रोत को एक label दें (जिससे साइडबार का नाम और उसका रूट बनता है), या एक स्पष्ट route सेट करें:
reference: [
openapi({
sources: [
{ label: "Public API", spec: "./public.json" }, // → /reference/public-api
{ label: "Admin API", route: "/admin", spec: "./admin.json" },
],
}),
],
spec एकल-प्रविष्टि वाले sources का संक्षिप्त रूप है, इसलिए sources की आवश्यकता केवल तभी होती है जब आपके पास एक से अधिक स्पेक हों। यदि दो स्पेक को अलग-अलग डिस्प्ले विकल्प चाहिए, जैसे कोड नमूनों का अलग सेट, तो इसके बजाय दो openapi() एडैप्टर सूचीबद्ध करें और प्रत्येक को अपना route दें। नेटिव पेजों के साथ एम्बेड किया गया Scalar संदर्भ सूची में एक अलग scalar() एडैप्टर के रूप में जोड़ा जाता है। स्रोत सूची के क्रम में रिज़ॉल्व किए जाते हैं। यदि दो स्रोत एक ही रूट पर रिज़ॉल्व होते हैं, तो पहला स्रोत रखा जाता है, और बिल्ड छोड़े गए स्रोत के बारे में चेतावनी देता है।
प्रति-स्रोत इंडेक्सिंग
जनरेट किए गए पेज डिफ़ॉल्ट रूप से खोज, llms.txt और क्रॉलर इंडेक्सिंग में शामिल होते हैं। कोई द्वितीयक या ओवरलैपिंग स्पेक इनमें से किसी से भी बाहर रह सकता है। इससे उसके पेज छिपते नहीं हैं और वह नेविगेशन में भी बना रहता है:
reference: [
openapi({
sources: [
{ label: "Public API", route: "/api", spec: "./public.json" },
{
label: "Platform API",
route: "/platform",
spec: "./platform.json",
includeInSearch: false,
includeInLlms: false,
noindex: true,
},
],
}),
],
includeInSearch: falseस्रोत के अवलोकन और ऑपरेशनों को साइट खोज से बाहर रखता है।includeInLlms: falseउन्हें दोनोंllms.txtफ़ाइलों से बाहर रखता है।noindex: trueक्रॉलर noindex मेटाडेटा जोड़ता है और पेजों को साइटमैप से हटा देता है।
प्रत्येक ऑपरेशन पेज का meta description ऑपरेशन का अपना description (या summary) होता है। इसके बाद एक जनरेट किया गया वाक्य जुड़ता है जो एंडपॉइंट का नाम बताता है — “Reference for the GET /pets endpoint in the Petstore API.”। इस तरह, छोटे एक-पंक्ति सारांशों वाले स्पेक से भी प्रत्येक पेज को अलग और स्निपेट के लायक लंबाई का विवरण मिलता है। यह वाक्य अंग्रेज़ी में होता है। यदि आपके स्पेक का पाठ किसी अन्य भाषा में लिखा गया है, तो स्रोत पर seoDescriptionSuffix: false सेट करें। इससे यह वाक्य हट जाता है और प्रत्येक पेज का विवरण केवल आपके लिखे पाठ से बनता है। जिस ऑपरेशन में न description हो और न summary, उसके लिए उसका शीर्षक (GET /pets) उपयोग होता है, ताकि किसी भी पेज का विवरण खाली न रहे:
reference: [
openapi({
sources: [{ spec: "./openapi.de.json", seoDescriptionSuffix: false }],
}),
],
scalar() एम्बेड इनमें से केवल noindex स्वीकार करता है। यह पहले से ही Blume की खोज और llms.txt से बाहर रहता है, इसलिए दोनों include* सेटिंग्स का वहाँ कोई प्रभाव नहीं होता।
प्राधिकरण
जो ऑपरेशन सुरक्षा आवश्यकताएँ घोषित करते हैं, उनके पैरामीटर के ऊपर एक Authorization अनुभाग दिखता है। जनरेट किए गए कोड नमूने स्कीम के अनुसार एक प्लेसहोल्डर क्रेडेंशियल भेजते हैं: Authorization: Bearer YOUR_TOKEN, एक API-कुंजी हेडर, या एक क्वेरी कुंजी। इसके लिए कुछ भी कॉन्फ़िगर नहीं करना पड़ता। Blume स्पेक से security पढ़ता है, इसलिए संदर्भ हमेशा उन्हीं नियमों को दिखाता है जो API वास्तव में लागू करता है।
OpenAPI के नियम स्पेक में लिखे अनुसार ही लागू होते हैं:
- किसी ऑपरेशन का अपना
securityदस्तावेज़ के रूट डिफ़ॉल्ट को ओवरराइड करता है।security: []उसे सार्वजनिक चिह्नित करता है, और उसके लिए कोई Authorization अनुभाग नहीं दिखता। - एकाधिक आवश्यकता प्रविष्टियाँ आपस में विकल्प होती हैं और “या” समूहों के रूप में दिखती हैं। एक प्रविष्टि के भीतर की सभी स्कीम एक साथ आवश्यक होती हैं। कोड नमूने पहले विकल्प पर आधारित होते हैं।
- खाली
{}प्रविष्टि का अर्थ है कि उस ऑपरेशन के लिए ऑथ वैकल्पिक है, और अनुभाग में यह बात बताई जाती है। - OAuth2 स्कोप प्रत्येक स्कीम के अनुसार सूचीबद्ध होते हैं।
components.securitySchemesमें दिए गए स्कीम केdescriptionइनलाइन दिखाए जाते हैं।
इसके बजाय Scalar एम्बेड करना
openapi() हमेशा Blume के अपने पेज रेंडर करता है। आप चाहें तो किसी एक रूट पर Scalar का स्व-निहित API संदर्भ UI एम्बेड कर सकते हैं, जिसका अपना साइडबार, खोज, थीम और अनुरोध क्लाइंट होता है। इसके लिए इस एडैप्टर के स्थान पर (या इसके साथ) blume/reference से एक scalar() एडैप्टर सूचीबद्ध करें। Scalar पेज बताता है कि एम्बेड क्या करता है और क्या नहीं। वहाँ यह भी बताया गया है कि Scalar के अपने विकल्प कैसे पास करें।