अपने Go API में Swagger जोड़ना

कोड एनोटेशन से ओपनएपीआई दस्तावेज़ स्वचालित रूप से उत्पन्न करें

Page content

API दस्तावेज़ीकरण किसी भी आधुनिक एप्लिकेशन के लिए अत्यंत महत्वपूर्ण है, और Go APIs के लिए Swagger for Go API (OpenAPI) उद्योग मानक बन गया है। Go Developers के लिए, swaggo एक सुंदर समाधान प्रदान करता है जो कोड एनोटेशन से सीधे व्यापक API दस्तावेज़ीकरण उत्पन्न करता है।

swagger api specs on agile board यह सुंदर छवि AI model Flux 1 dev द्वारा बनाई गई है।

Go APIs के लिए Swagger का महत्व

REST APIs को बनाते समय, दस्तावेज़ीकरण अक्सर कोड के विकसित होने के साथ अपडेट नहीं रहता है। Swagger इस समस्या का समाधान करता है कोड से दस्तावेज़ीकरण उत्पन्न करके, जिससे यह सुनिश्चित होता है कि यह आपके कार्यान्वयन के साथ समकालिक रहता है। इंटरैक्टिव Swagger UI डेवलपर्स को ब्राउज़र से सीधे एंडपॉइंट्स को टेस्ट करने की अनुमति देता है, जिससे डेवलपर अनुभव महत्वपूर्ण रूप से सुधर जाता है।

माइक्रोसर्विसेज या पब्लिक APIs को बनाने वाले टीमों के लिए, Swagger दस्तावेज़ीकरण निम्नलिखित के लिए आवश्यक हो जाता है:

  • क्लाइंट जनरेशन: कई भाषाओं में क्लाइंट लाइब्रेरी स्वचालित रूप से बनाएं
  • कॉन्ट्रैक्ट टेस्टिंग: अनुरोधों और प्रतिक्रियाओं को परिभाषित स्कीमाओं के खिलाफ सत्यापित करें
  • टीम सहयोग: API कॉन्ट्रैक्ट्स के लिए एकल स्रोत सत्यता प्रदान करें
  • डेवलपर ऑनबोर्डिंग: नए टीम सदस्य APIs को इंटरैक्टिव रूप से खोज सकते हैं

swaggo के साथ शुरुआत

swaggo लाइब्रेरी Go एप्लिकेशनों में Swagger समर्थन जोड़ने के लिए सबसे लोकप्रिय उपकरण है। यह अपने कोड में विशेष टिप्पणियों को पार्स करके OpenAPI 3.0 स्पेसिफिकेशन फाइलें उत्पन्न करता है।

इंस्टॉलेशन

पहले swag CLI उपकरण को इंस्टॉल करें:

go install github.com/swaggo/swag/cmd/swag@latest

फिर अपने फ्रेमवर्क के लिए उपयुक्त Swagger मिडलवेयर पैकेज जोड़ें। Gin के लिए:

go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files

Echo के लिए:

go get -u github.com/swaggo/echo-swagger

Fiber के लिए:

go get -u github.com/gofiber/swagger

बेसिक कॉन्फ़िगरेशन

अपने main.go फाइल में सामान्य API जानकारी जोड़ने से शुरू करें। जैसे कि आप एक REST API in Go को संरचित करते हैं, एनोटेशन स्पष्ट और वर्णनात्मक होने चाहिए:

// @title           Product API
// @version         1.0
// @description     A product management API with Swagger documentation
// @termsOfService  http://swagger.io/terms/

// @contact.name   API Support
// @contact.url    http://www.swagger.io/support
// @contact.email  support@swagger.io

// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html

// @host      localhost:8080
// @BasePath  /api/v1

// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and JWT token.

func main() {
    // Your application code
}

Gin Framework के साथ कार्यान्वयन

Gin का उपयोग करके एक पूर्ण उदाहरण लागू करें। पहले अपने डेटा मॉडल्स को स्ट्रक्च टैग्स के साथ परिभाषित करें:

type Product struct {
    ID          int     `json:"id" example:"1"`
    Name        string  `json:"name" example:"Laptop" binding:"required"`
    Description string  `json:"description" example:"High-performance laptop"`
    Price       float64 `json:"price" example:"999.99" binding:"required,gt=0"`
    Stock       int     `json:"stock" example:"50"`
}

type ErrorResponse struct {
    Error   string `json:"error" example:"Invalid input"`
    Message string `json:"message" example:"Product name is required"`
}

अब अपने हैंडलर फंक्शंस को एनोटेट करें। डेटाबेस ऑपरेशंस के साथ काम करते समय, ये एनोटेशन डेटा फ्लो को दस्तावेज़ीकरण करने में मदद करते हैं:

// GetProduct godoc
// @Summary      Get product by ID
// @Description  Retrieve a single product by its unique identifier
// @Tags         products
// @Accept       json
// @Produce      json
// @Param        id   path      int  true  "Product ID"
// @Success      200  {object}  Product
// @Failure      400  {object}  ErrorResponse
// @Failure      404  {object}  ErrorResponse
// @Router       /products/{id} [get]
func GetProduct(c *gin.Context) {
    id := c.Param("id")
    // Implementation here
    c.JSON(200, Product{ID: 1, Name: "Laptop", Price: 999.99})
}

// CreateProduct godoc
// @Summary      Create a new product
// @Description  Add a new product to the catalog
// @Tags         products
// @Accept       json
// @Produce      json
// @Param        product  body      Product  true  "Product object"
// @Success      201      {object}  Product
// @Failure      400      {object}  ErrorResponse
// @Security     Bearer
// @Router       /products [post]
func CreateProduct(c *gin.Context) {
    var product Product
    if err := c.ShouldBindJSON(&product); err != nil {
        c.JSON(400, ErrorResponse{Error: "Bad Request", Message: err.Error()})
        return
    }
    // Save to database
    c.JSON(201, product)
}

दस्तावेज़ीकरण उत्पन्न करना

कोड को एनोटेट करने के बाद, Swagger दस्तावेज़ीकरण उत्पन्न करें:

swag init

यह एक docs फोल्डर बनाता है जिसमें swagger.json, swagger.yaml, और Go फाइलें होती हैं। Swagger एंडपॉइंट को इम्पोर्ट और रजिस्टर करें:

package main

import (
    "github.com/gin-gonic/gin"
    swaggerFiles "github.com/swaggo/files"
    ginSwagger "github.com/swaggo/gin-swagger"

    _ "yourproject/docs" // Import generated docs
)

func main() {
    r := gin.Default()

    // API routes
    v1 := r.Group("/api/v1")
    {
        v1.GET("/products/:id", GetProduct)
        v1.POST("/products", CreateProduct)
    }

    // Swagger endpoint
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

    r.Run(":8080")
}

अब अपने इंटरैक्टिव API दस्तावेज़ीकरण को http://localhost:8080/swagger/index.html पर एक्सेस करें।

Echo Framework के साथ कार्यान्वयन

Echo उपयोगकर्ता एक समान पैटर्न का पालन करते हैं लेकिन Echo-विशिष्ट मिडलवेयर के साथ:

package main

import (
    "github.com/labstack/echo/v4"
    echoSwagger "github.com/swaggo/echo-swagger"

    _ "yourproject/docs"
)

func main() {
    e := echo.New()

    // API routes
    api := e.Group("/api/v1")
    api.GET("/products/:id", getProduct)
    api.POST("/products", createProduct)

    // Swagger endpoint
    e.GET("/swagger/*", echoSwagger.WrapHandler)

    e.Start(":8080")
}

Fiber Framework के साथ कार्यान्वयन

Fiber का कार्यान्वयन उतना ही सरल है:

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/swagger"

    _ "yourproject/docs"
)

func main() {
    app := fiber.New()

    // API routes
    api := app.Group("/api/v1")
    api.Get("/products/:id", getProduct)
    api.Post("/products", createProduct)

    // Swagger endpoint
    app.Get("/swagger/*", swagger.HandlerDefault)

    app.Listen(":8080")
}

उन्नत Swagger एनोटेशन

जटिल रिक्वेस्ट बॉडीज को दस्तावेज़ीकरण करना

नस्टेड स्ट्रक्चर्स या एरेयों के लिए:

type CreateOrderRequest struct {
    CustomerID int           `json:"customer_id" example:"123" binding:"required"`
    Items      []OrderItem   `json:"items" binding:"required,min=1"`
    ShippingAddress Address  `json:"shipping_address" binding:"required"`
}

type OrderItem struct {
    ProductID int `json:"product_id" example:"1" binding:"required"`
    Quantity  int `json:"quantity" example:"2" binding:"required,min=1"`
}

type Address struct {
    Street  string `json:"street" example:"123 Main St" binding:"required"`
    City    string `json:"city" example:"New York" binding:"required"`
    ZipCode string `json:"zip_code" example:"10001" binding:"required"`
}

// CreateOrder godoc
// @Summary      Create a new order
// @Description  Create an order with multiple items and shipping information
// @Tags         orders
// @Accept       json
// @Produce      json
// @Param        order  body      CreateOrderRequest  true  "Order details"
// @Success      201    {object}  Order
// @Failure      400    {object}  ErrorResponse
// @Failure      422    {object}  ErrorResponse
// @Security     Bearer
// @Router       /orders [post]
func CreateOrder(c *gin.Context) {
    // Implementation
}

फाइल अपलोड्स को दस्तावेज़ीकरण करना

// UploadImage godoc
// @Summary      Upload product image
// @Description  Upload an image file for a product
// @Tags         products
// @Accept       multipart/form-data
// @Produce      json
// @Param        id    path      int   true  "Product ID"
// @Param        file  formData  file  true  "Image file"
// @Success      200   {object}  map[string]string
// @Failure      400   {object}  ErrorResponse
// @Security     Bearer
// @Router       /products/{id}/image [post]
func UploadImage(c *gin.Context) {
    file, _ := c.FormFile("file")
    // Handle upload
}

क्वेरी पैरामीटर्स और पेजिनेशन

// ListProducts godoc
// @Summary      List products with pagination
// @Description  Get paginated list of products with optional filtering
// @Tags         products
// @Accept       json
// @Produce      json
// @Param        page      query     int     false  "Page number" default(1)
// @Param        page_size query     int     false  "Items per page" default(10)
// @Param        category  query     string  false  "Filter by category"
// @Param        min_price query     number  false  "Minimum price"
// @Param        max_price query     number  false  "Maximum price"
// @Success      200       {array}   Product
// @Failure      400       {object}  ErrorResponse
// @Router       /products [get]
func ListProducts(c *gin.Context) {
    // Implementation with pagination
}

प्रमाणिकरण और सुरक्षा

अपने API में विभिन्न प्रमाणिकरण विधियों को दस्तावेज़ीकरण करें। मल्टी-टेनेंट एप्लिकेशंस के लिए, सही प्रमाणिकरण दस्तावेज़ीकरण महत्वपूर्ण है:

Bearer टोकन प्रमाणिकरण

// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and JWT token.

API Key प्रमाणिकरण

// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key
// @description API key for authentication

OAuth2 प्रमाणिकरण

// @securitydefinitions.oauth2.application OAuth2Application
// @tokenUrl https://example.com/oauth/token
// @scope.write Grants write access
// @scope.admin Grants read and write access to administrative information

बेसिक प्रमाणिकरण

// @securityDefinitions.basic BasicAuth

विशिष्ट एंडपॉइंट्स पर सुरक्षा लागू करें:

// @Security Bearer
// @Security ApiKeyAuth

Swagger UI को कस्टमाइज़ करना

आप Swagger UI की उपस्थिति और व्यवहार को कस्टमाइज़ कर सकते हैं:

// Custom configuration
url := ginSwagger.URL("http://localhost:8080/swagger/doc.json")
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))

// With custom title
r.GET("/swagger/*any", ginSwagger.WrapHandler(
    swaggerFiles.Handler,
    ginSwagger.URL("http://localhost:8080/swagger/doc.json"),
    ginSwagger.DefaultModelsExpandDepth(-1),
))

उत्पादन में Swagger को निष्क्रिय करने के लिए:

if os.Getenv("ENV") != "production" {
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}

CI/CD के साथ एकीकरण

अपने CI/CD पाइपलाइन में स्वागर दस्तावेज़ जनरेशन को स्वचालित करें:

# GitHub Actions उदाहरण
name: Generate Swagger Docs
on: [push]

jobs:
  swagger:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.21'

      - name: Install swag
        run: go install github.com/swaggo/swag/cmd/swag@latest

      - name: Generate Swagger docs
        run: swag init

      - name: Commit docs
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add docs/
          git commit -m "Update Swagger documentation" || exit 0
          git push          

सर्वोत्तम प्रथाएँ

1. एकसंग अनोटेशन शैली

सभी एंडपॉइंट्स पर एकसंग फॉर्मेटिंग बनाए रखें:

// HandlerName godoc
// @Summary      संक्षिप्त वर्णन (50 अक्षरों से कम)
// @Description  एंडपॉइंट के कार्य का विस्तृत वर्णन
// @Tags         resource-name
// @Accept       json
// @Produce      json
// @Param        name  location  type  required  "वर्णन"
// @Success      200   {object}  ResponseType
// @Failure      400   {object}  ErrorResponse
// @Router       /path [method]

2. वर्णनात्मक उदाहरणों का उपयोग करें

API उपभोक्ताओं की मदद के लिए वास्तविक उदाहरण जोड़ें:

type User struct {
    ID        int       `json:"id" example:"1"`
    Email     string    `json:"email" example:"user@example.com"`
    CreatedAt time.Time `json:"created_at" example:"2025-01-15T10:30:00Z"`
}

3. सभी प्रतिक्रिया कोडों का दस्तावेज़ीकरण करें

सभी संभावित HTTP स्थिति कोडों को शामिल करें:

// @Success      200  {object}  Product
// @Success      201  {object}  Product
// @Failure      400  {object}  ErrorResponse "Bad Request"
// @Failure      401  {object}  ErrorResponse "Unauthorized"
// @Failure      403  {object}  ErrorResponse "Forbidden"
// @Failure      404  {object}  ErrorResponse "Not Found"
// @Failure      422  {object}  ErrorResponse "Validation Error"
// @Failure      500  {object}  ErrorResponse "Internal Server Error"

4. अपने API का संस्करण बनाएं

बेस पाथ में उचित संस्करणिंग का उपयोग करें:

// @BasePath  /api/v1

और अपने कोड को उचित रूप से व्यवस्थित करें:

v1 := r.Group("/api/v1")
v2 := r.Group("/api/v2")

5. संबंधित एंडपॉइंट्स को समूहीकृत करें

एंडपॉइंट्स को तार्किक रूप से व्यवस्थित करने के लिए टैग का उपयोग करें:

// @Tags products
// @Tags orders
// @Tags users

6. दस्तावेज़ों को अपडेट रखें

हर कमिट से पहले swag init चलाएं या इसे अपने बिल्ड प्रक्रिया में एकीकृत करें:

#!/bin/bash
# pre-commit hook
swag init
git add docs/

स्वागर दस्तावेज़ों का परीक्षण

सर्वरलेस आर्किटेक्चर जैसे AWS Lambda के साथ काम करते समय, अपने API दस्तावेज़ों का परीक्षण करना और भी महत्वपूर्ण हो जाता है:

func TestSwaggerGeneration(t *testing.T) {
    // Verify swagger.json exists
    _, err := os.Stat("./docs/swagger.json")
    if err != nil {
        t.Fatal("swagger.json not found, run 'swag init'")
    }

    // Verify swagger endpoint responds
    r := setupRouter()
    w := httptest.NewRecorder()
    req, _ := http.NewRequest("GET", "/swagger/index.html", nil)
    r.ServeHTTP(w, req)

    assert.Equal(t, 200, w.Code)
}

सामान्य समस्याएँ और समाधान

दस्तावेज़ अपडेट नहीं हो रहे हैं

अगर परिवर्तन दिखाई नहीं देते हैं, सुनिश्चित करें कि आप दस्तावेज़ पुनः जनरेट कर रहे हैं:

swag init --parseDependency --parseInternal

--parseDependency फ्लैग बाहरी निर्भरताओं को पार्स करता है, और --parseInternal आंतरिक पैकेजों को पार्स करता है।

कस्टम टाइप्स को पहचाना नहीं जाता

बाहरी पैकेजों के टाइप्स के लिए, swaggertype टैग का उपयोग करें:

type CustomTime struct {
    time.Time
}

func (CustomTime) SwaggerDoc() map[string]string {
    return map[string]string{
        "time": "RFC3339 timestamp",
    }
}

या swaggertype टैग का उपयोग करें:

type Product struct {
    ID        int        `json:"id"`
    UpdatedAt CustomTime `json:"updated_at" swaggertype:"string" format:"date-time"`
}

एरेय और एन्यूम्स

एरेय टाइप्स और एन्यूम्स का दस्तावेज़ीकरण करें:

type Filter struct {
    Status []string `json:"status" enums:"active,inactive,pending"`
    Tags   []string `json:"tags"`
}

// @Param  status  query  string  false  "Status filter" Enums(active, inactive, pending)

वैकल्पिक दृष्टिकोण

हालांकि swaggo सबसे लोकप्रिय विकल्प है, अन्य विकल्प भी उपलब्ध हैं:

go-swagger

एक अधिक फीचर-रिच लेकिन जटिल विकल्प:

brew install go-swagger
swagger generate spec -o ./swagger.json

मैनुअल ओपनAPI फाइलें

पूर्ण नियंत्रण के लिए, ओपनAPI स्पेसिफिकेशन्स को मैनुअल रूप से YAML में लिखें:

openapi: 3.0.0
info:
  title: Product API
  version: 1.0.0
paths:
  /products:
    get:
      summary: List products
      responses:
        '200':
          description: Success

फिर सर्व करें:

r.StaticFile("/openapi.yaml", "./openapi.yaml")

AI और LLMs के साथ एकीकरण

AI सेवाओं के साथ एकीकृत APIs बनाते समय, उचित दस्तावेज़ीकरण महत्वपूर्ण हो जाता है। उदाहरण के लिए, संरचित LLM आउटपुट्स के साथ काम करते समय, Swagger जटिल रिक्वेस्ट और रिस्पॉन्स स्कीमास का दस्तावेज़ीकरण करने में मदद करता है:

type LLMRequest struct {
    Prompt      string            `json:"prompt" example:"Summarize this text"`
    Model       string            `json:"model" example:"qwen2.5:latest"`
    Temperature float64           `json:"temperature" example:"0.7" minimum:"0" maximum:"2"`
    MaxTokens   int               `json:"max_tokens" example:"1000" minimum:"1"`
    Schema      map[string]interface{} `json:"schema,omitempty"`
}

// GenerateStructured godoc
// @Summary      Generate structured LLM output
// @Description  Generate text with constrained output schema
// @Tags         llm
// @Accept       json
// @Produce      json
// @Param        request  body      LLMRequest  true  "LLM parameters"
// @Success      200      {object}  map[string]interface{}
// @Failure      400      {object}  ErrorResponse
// @Router       /llm/generate [post]
func GenerateStructured(c *gin.Context) {
    // Implementation
}

प्रदर्शन विचार

स्वागर दस्तावेज़ों का प्रदर्शन पर न्यूनतम प्रभाव पड़ता है:

  • बिल्ड समय: swag init अधिकांश प्रोजेक्ट्स के लिए 1-3 सेकंड लेता है
  • रनटाइम: दस्तावेज़ स्टार्टअप पर एक बार लोड किए जाते हैं
  • मेमोरी: आमतौर पर बाइनरी साइज में 1-2MB जोड़ता है
  • रिस्पॉन्स समय: API एंडपॉइंट्स पर कोई प्रभाव नहीं पड़ता

बहुत बड़े APIs (100+ एंडपॉइंट्स) के लिए, विचार करें:

  • कई स्वागर फाइलों में विभाजित करें
  • स्वागर UI एसेट्स को लेजी-लोड करें
  • दस्तावेज़ों को एक अलग सेवा से सर्व करें

सुरक्षा विचार

स्वागर दस्तावेज़ों को एक्सपोज करते समय:

  1. प्रोडक्शन में निष्क्रिय करें (अगर API आंतरिक है):
if os.Getenv("ENV") == "production" {
    // Don't register Swagger endpoint
    return
}
  1. प्रमाणिकरण जोड़ें:
authorized := r.Group("/swagger")
authorized.Use(AuthMiddleware())
authorized.GET("/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
  1. एंडपॉइंट पर रेट लिमिट लगाएं:
r.GET("/swagger/*any", RateLimitMiddleware(), ginSwagger.WrapHandler(swaggerFiles.Handler))
  1. कभी भी आंतरिक विवरणों को एक्सपोज न करें:
  • आंतरिक एंडपॉइंट्स का दस्तावेज़ीकरण न करें
  • डेटाबेस स्कीमास को सीधे एक्सपोज न करें
  • दस्तावेज़ों में त्रुटि संदेशों को साफ़ करें

निष्कर्ष

अपने Go API में स्वागर दस्तावेज़ जोड़ना डेवलपर अनुभव को अंदाजे से अन्वेषण से गाइडेड अन्वेषण में बदल देता है। swaggo लाइब्रेरी इस प्रक्रिया को सरल बनाती है अपने कोड अनोटेशन्स से व्यापक ओपनAPI दस्तावेज़ जनरेट करके।

मुख्य बिंदु:

  • बुनियादी अनोटेशन्स से शुरू करें और धीरे-धीरे बढ़ाएं
  • CI/CD के माध्यम से कोड के साथ दस्तावेज़ों को सिंक्रोनाइज़ रखें
  • विकास के दौरान स्वागर UI का उपयोग इंटरैक्टिव परीक्षण के लिए करें
  • प्रमाणिकरण, त्रुटियों और एज केसों का विस्तृत दस्तावेज़ीकरण करें
  • दस्तावेज़ों को एक्सपोज करने के सुरक्षा निहितार्थों पर विचार करें

चाहे आप माइक्रोसर्विसेस, पब्लिक APIs, या आंतरिक टूल्स बनाएं, स्वागर दस्तावेज़ों का निवेश कम समर्थन बोझ, तेज़ ऑनबोर्डिंग, और बेहतर API डिज़ाइन में लाभ देता है। अनोटेशन सिंटैक्स सीखने का आरंभिक निवेश जल्द ही रूटीन बन जाता है, और स्वचालित जनरेशन सुनिश्चित करता है कि आपका दस्तावेज़ कभी भी आपकी इम्प्लीमेंटेशन से पीछे न रहे।

Go डेवलपर्स के लिए, मजबूत टाइपिंग, कोड जनरेशन, और swaggo के अनोटेशन सिस्टम का संयोजन एक शक्तिशाली वर्कफ्लो बनाता है जो API दस्तावेज़ीकरण को विकास प्रक्रिया का एक प्राकृतिक हिस्सा बनाता है, न कि एक बाद की सोच।

उपयोगी लिंक्स

बाहरी संसाधन