مبدل Curl به Go

تبدیل دستورات curl به کد Go - تولید کد Go net/http آماده استفاده برای درخواست‌های API

اطلاعیه حریم خصوصی: این ابزار حرفه‌ای تبدیل امن به کد Go را با حفاظت حریم خصوصی سطح سازمانی فراهم می‌کند. ما هیچ داده‌ای که ارسال می‌کنید را ذخیره نمی‌کنیم و محرمانگی کامل را برای کار توسعه API شما تضمین می‌کنیم.

تولیدکننده کد Go

// Go code will appear here
// Example:
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	url := "https://api.example.com/data"
	
	// Create request payload
	payload := map[string]interface{}{
		"name": "test",
	}
	
	jsonData, err := json.Marshal(payload)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return
	}
	
	// Create request
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}
	
	// Add headers
	req.Header.Set("Content-Type", "application/json")
	
	// Send request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()
	
	// Read response
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}
	
	fmt.Println("Status:", resp.Status)
	fmt.Println("Response:", string(body))
}

دستورات curl رایج برای تست API Go

در اینجا برخی دستورات curl رایج که می‌توانید به کد Go تبدیل کنید آمده است:

مثال‌های HTTP Go

بسته net/http در Go روشی قدرتمند و کارآمد برای ارسال درخواست‌های HTTP فراهم می‌کند. در اینجا برخی الگوهای رایج HTTP Go آمده است:

آپلود فایل با Go

package main

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
)

func main() {
	url := "https://api.example.com/upload"
	
	// Create a buffer to store the multipart form
	var requestBody bytes.Buffer
	multipartWriter := multipart.NewWriter(&requestBody)
	
	// Open the file
	file, err := os.Open("document.pdf")
	if err != nil {
		fmt.Println("Error opening file:", err)
		return
	}
	defer file.Close()
	
	// Create a form file field
	fileWriter, err := multipartWriter.CreateFormFile("file", filepath.Base("document.pdf"))
	if err != nil {
		fmt.Println("Error creating form file:", err)
		return
	}
	
	// Copy the file content to the form field
	_, err = io.Copy(fileWriter, file)
	if err != nil {
		fmt.Println("Error copying file to form:", err)
		return
	}
	
	// Add other form fields if needed
	multipartWriter.WriteField("description", "Sample document upload")
	
	// Close the multipart writer
	multipartWriter.Close()
	
	// Create request
	req, err := http.NewRequest("POST", url, &requestBody)
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}
	
	// Set the content type with the boundary
	req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
	req.Header.Set("Authorization", "Bearer YOUR_TOKEN_HERE")
	
	// Send request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()
	
	// Read response
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}
	
	fmt.Println("Status:", resp.Status)
	fmt.Println("Response:", string(body))
}

HTTP Go با مهلت زمانی و مدیریت خطا

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
)

func main() {
	// Create a context with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	
	// Create request
	req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}
	
	// Send request
	client := &http.Client{}
	resp, err := client.Do(req)
	
	// Handle errors
	if err != nil {
		if ctx.Err() == context.DeadlineExceeded {
			fmt.Println("Request timed out")
		} else {
			fmt.Println("Error sending request:", err)
		}
		return
	}
	defer resp.Body.Close()
	
	// Check status code
	if resp.StatusCode != http.StatusOK {
		fmt.Printf("Server returned non-200 status: %s\n", resp.Status)
		body, _ := ioutil.ReadAll(resp.Body)
		fmt.Println("Response body:", string(body))
		return
	}
	
	// Read and parse response
	var data map[string]interface{}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response:", err)
		return
	}
	
	err = json.Unmarshal(body, &data)
	if err != nil {
		fmt.Println("Error parsing JSON:", err)
		fmt.Println("Raw response:", string(body))
		return
	}
	
	fmt.Println("Successfully received data:", data)
}

نحوه استفاده از مبدل کد Go

۱. استفاده پایه

دستور curl خود را کپی کنید → در کادر ورودی جایگذاری کنید → فوراً کد Go دریافت کنید

۲. پیاده‌سازی مدیریت خطای مناسب

// Always check for errors in Go
resp, err := client.Do(req)
if err != nil {
	fmt.Println("Error sending request:", err)
	return
}
defer resp.Body.Close()

// Check status code
if resp.StatusCode != http.StatusOK {
	fmt.Printf("Server returned non-200 status: %s\n", resp.Status)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println("Response body:", string(body))
	return
}

۳. استفاده از Context برای مهلت‌های زمانی

// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

// Create request with context
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)
if err != nil {
	fmt.Println("Error creating request:", err)
	return
}

// Send request
client := &http.Client{}
resp, err := client.Do(req)

// Check for timeout
if err != nil {
	if ctx.Err() == context.DeadlineExceeded {
		fmt.Println("Request timed out")
	} else {
		fmt.Println("Error sending request:", err)
	}
	return
}

سؤالات متداول درباره درخواست‌های HTTP Go

س: کلاینت HTTP Go چگونه با curl متفاوت است؟

ج: در حالی که curl یک ابزار خط فرمان برای ارسال درخواست‌های HTTP است، بسته net/http در Go یک API برنامه‌نویسی ارائه می‌دهد. Go تایپ قوی‌تر، پشتیبانی از همزمانی داخلی و ادغام بهتر با کد برنامه شما را ارائه می‌دهد، در حالی که curl در تست‌های موردی سریع و اسکریپت‌نویسی برتری دارد.

س: چرا Go از defer برای بستن بدنه پاسخ استفاده می‌کند؟

ج: Go از defer resp.Body.Close() استفاده می‌کند تا اطمینان حاصل شود که منابع حتی در صورت بروز خطا در ادامه تابع، به درستی آزاد می‌شوند. این الگو در Go متداول است و از نشت منابعی که ممکن است در صورت فراموش کردن بستن بدنه در تمام مسیرهای کد ممکن رخ دهد، جلوگیری می‌کند.

س: چگونه پاسخ‌های جریانی را در Go مدیریت کنم؟

ج: به جای استفاده از ioutil.ReadAll()، می‌توانید بدنه پاسخ را به صورت جریانی با استفاده از io.Copy() یا با خواندن قطعات با یک بافر پردازش کنید. این به ویژه برای پاسخ‌های بزرگ که بارگذاری کل بدنه در حافظه ناکارآمد خواهد بود، مفید است.

س: آیا می‌توانم کلاینت‌های HTTP را در Go مجدداً استفاده کنم؟

ج: بله، و این توصیه می‌شود! ایجاد یک http.Client واحد و استفاده مجدد از آن در درخواست‌های مختلف امکان استخر اتصال و بهبود عملکرد را فراهم می‌کند. کلاینت برای همزمانی ایمن است و می‌تواند بدون نیاز به همگام‌سازی اضافی بین goroutine‌ها به اشتراک گذاشته شود.

س: چگونه لغو درخواست را در Go پیاده‌سازی کنم؟

ج: بسته context در Go امکان لغو درخواست را به شکلی زیبا فراهم می‌کند. یک context با context.WithCancel() یا context.WithTimeout() ایجاد کنید، سپس آن را به http.NewRequestWithContext() منتقل کنید. می‌توانید درخواست را در هر زمان با فراخوانی تابع لغو، لغو کنید.

س: معادل پرچم -k/--insecure در curl در Go چیست؟

ج: برای رد کردن تأیید گواهی TLS (مانند پرچم -k در curl)، یک Transport سفارشی در کلاینت HTTP خود پیکربندی کنید: client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}} با این حال، این باید فقط برای تست استفاده شود، زیرا بررسی‌های امنیتی را دور می‌زند.

س: چگونه تغییر مسیرها را در Go در مقایسه با curl مدیریت کنم؟

ج: کلاینت HTTP در Go به طور خودکار تغییر مسیرها را دنبال می‌کند (تا ۱۰ مورد به طور پیش‌فرض)، مشابه curl. برای سفارشی‌سازی این رفتار، یک تابع CheckRedirect سفارشی در کلاینت HTTP خود تنظیم کنید تا مدیریت تغییر مسیر را کنترل کنید یا کاملاً از تغییر مسیرها جلوگیری کنید.

مرجع دستور Curl برای تست API در Go

درک دستورات curl برای تست مؤثر API در Go ضروری است. در اینجا مرجع سریعی از گزینه‌های رایج curl که مبدل ما پشتیبانی می‌کند آمده است:

نحو پایه curl

curl [options] [URL]

گزینه‌های رایج curl

تبدیل دستورات پیچیده curl

مبدل Go ما دستورات پیچیده curl شامل چندین هدر، احراز هویت، داده‌های محتوا و گزینه‌های مختلف را پشتیبانی می‌کند. به سادگی دستور curl خود را جایگذاری کنید و کد Go تمیز و مدرن با استفاده از بسته net/http دریافت کنید.

بهترین شیوه‌های HTTP Go

هنگام کار با بسته net/http در Go، این بهترین شیوه‌ها را برای تعاملات API کارآمد و امن دنبال کنید:

۱. همیشه بدنه پاسخ را ببندید

resp, err := client.Do(req)
if err != nil {
	fmt.Println("Error sending request:", err)
	return
}
defer resp.Body.Close() // Important: prevents resource leaks

۲. از کلاینت HTTP سفارشی استفاده کنید

client := &http.Client{
	Timeout: 10 * time.Second,
	Transport: &http.Transport{
		MaxIdleConns:        100,
		MaxIdleConnsPerHost: 20,
		IdleConnTimeout:     90 * time.Second,
	},
}

resp, err := client.Do(req)
if err != nil {
	fmt.Println("Error sending request:", err)
	return
}

۳. مدیریت خطای جامع را پیاده‌سازی کنید

resp, err := client.Do(req)
if err != nil {
	var netErr net.Error
	if errors.As(err, &netErr) && netErr.Timeout() {
		fmt.Println("Request timed out")
	} else if errors.Is(err, context.DeadlineExceeded) {
		fmt.Println("Context deadline exceeded")
	} else {
		fmt.Println("Error sending request:", err)
	}
	return
}
defer resp.Body.Close()

// Check status code
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Printf("Error status: %d %s\n", resp.StatusCode, resp.Status)
	fmt.Printf("Response body: %s\n", string(body))
	return
}

// Read response
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
	fmt.Println("Error reading response body:", err)
	return
}

// Process response data
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
	fmt.Println("Error parsing JSON:", err)
	fmt.Println("Raw response:", string(body))
	return
}

۴. از Context برای کنترل مهلت زمانی و لغو استفاده کنید

// Create context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() // Important: prevents context leaks

// Create request with context
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)
if err != nil {
	fmt.Println("Error creating request:", err)
	return
}

// Send request
resp, err := client.Do(req)
// Error handling...

۵. از Struct‌ها برای سریال‌سازی و عدم سریال‌سازی JSON استفاده کنید

// Define request and response structs
type User struct {
	ID    int    `json:"id,omitempty"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

// Create request data
user := User{
	Name:  "John Doe",
	Email: "[email protected]",
}

// Serialize to JSON
jsonData, err := json.Marshal(user)
if err != nil {
	fmt.Println("Error marshaling JSON:", err)
	return
}

// Create request
req, err := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonData))
// Set headers, send request, etc...

// Deserialize response
var responseUser User
if err := json.Unmarshal(body, &responseUser); err != nil {
	fmt.Println("Error parsing JSON response:", err)
	return
}
fmt.Printf("Created user with ID: %d\n", responseUser.ID)