แปลงคำสั่ง curl เป็นโค้ด Go - สร้างโค้ด Go net/http พร้อมใช้งานสำหรับคำขอ API
// 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 ทั่วไปที่คุณสามารถแปลงเป็นโค้ด Go ได้:
curl https://api.example.com/users
curl -X POST -H "Content-Type: application/json" -d '{"name":"John","email":"[email protected]"}' https://api.example.com/users
curl -X PUT -H "Authorization: Bearer token123" -d '{"status":"active"}' https://api.example.com/users/1
curl -X DELETE https://api.example.com/users/1
curl -H "X-API-Key: abc123" -H "Accept: application/json" https://api.example.com/data
แพ็คเกจ net/http ของ Go มอบวิธีที่ทรงพลังและมีประสิทธิภาพในการทำคำขอ HTTP นี่คือรูปแบบ HTTP ทั่วไปของ 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)) }
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) }
คัดลอกคำสั่ง 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 }
// 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 }
คำตอบ: ในขณะที่ curl เป็นเครื่องมือบรรทัดคำสั่งสำหรับการทำคำขอ HTTP แพ็คเกจ net/http ของ Go ให้ API แบบโปรแกรม Go มีการพิมพ์ที่แข็งแกร่งกว่า, การสนับสนุนการทำงานพร้อมกันในตัว และการผสานรวมที่ดีกว่ากับโค้ดแอปพลิเคชันของคุณ ในขณะที่ curl เหมาะสำหรับการทดสอบเฉพาะกิจอย่างรวดเร็วและการเขียนสคริปต์
คำตอบ: Go ใช้ defer resp.Body.Close() เพื่อให้แน่ใจว่าทรัพยากรถูกปล่อยอย่างเหมาะสมแม้ว่าจะเกิดข้อผิดพลาดในภายหลังในฟังก์ชัน รูปแบบนี้เป็นแบบแผนใน Go และป้องกันการรั่วไหลของทรัพยากรที่อาจเกิดขึ้นหากคุณลืมปิดเนื้อหาในทุกเส้นทางโค้ดที่เป็นไปได้
คำตอบ: แทนที่จะใช้ ioutil.ReadAll()
คุณสามารถประมวลผลเนื้อหาการตอบสนองเป็นสตรีมโดยใช้ io.Copy()
หรือโดยการอ่านเป็นชิ้นๆ ด้วยบัฟเฟอร์ สิ่งนี้มีประโยชน์โดยเฉพาะสำหรับการตอบสนองขนาดใหญ่ที่การโหลดเนื้อหาทั้งหมดเข้าหน่วยความจำจะไม่มีประสิทธิภาพ
คำตอบ: ได้ และแนะนำให้ทำ! การสร้าง http.Client
เดียวและนำกลับมาใช้ใหม่ในคำขอต่างๆ ช่วยให้มีการรวมการเชื่อมต่อและปรับปรุงประสิทธิภาพ ไคลเอนต์มีความปลอดภัยในการทำงานพร้อมกันและสามารถแชร์ระหว่าง goroutines โดยไม่ต้องมีการซิงโครไนซ์เพิ่มเติม
A: แพ็คเกจ context ของ Go มอบการยกเลิกคำขอที่สง่างาม สร้าง context ด้วย context.WithCancel()
หรือ context.WithTimeout()
จากนั้นส่งไปยัง http.NewRequestWithContext()
คุณสามารถยกเลิกคำขอได้ทุกเมื่อโดยการเรียกฟังก์ชันยกเลิก
คำตอบ: เพื่อข้ามการตรวจสอบใบรับรอง TLS (เหมือนแฟล็ก -k ของ curl) ให้กำหนดค่า Transport ที่กำหนดเองในไคลเอนต์ HTTP ของคุณ: client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}}
อย่างไรก็ตาม สิ่งนี้ควรใช้สำหรับการทดสอบเท่านั้น เนื่องจากเป็นการข้ามการตรวจสอบความปลอดภัย
คำตอบ: ไคลเอนต์ HTTP ของ Go ติดตามการเปลี่ยนเส้นทางโดยอัตโนมัติ (สูงสุด 10 ครั้งโดยค่าเริ่มต้น) เช่นเดียวกับ curl เพื่อปรับแต่งพฤติกรรมนี้ ให้กำหนดฟังก์ชัน CheckRedirect
ที่กำหนดเองในไคลเอนต์ HTTP ของคุณเพื่อควบคุมการจัดการการเปลี่ยนเส้นทางหรือป้องกันการเปลี่ยนเส้นทางทั้งหมด
การเข้าใจคำสั่ง curl มีความสำคัญสำหรับการทดสอบ API ด้วย Go ที่มีประสิทธิภาพ นี่คือข้อมูลอ้างอิงอย่างรวดเร็วของตัวเลือก curl ทั่วไปที่เครื่องมือแปลงของเรารองรับ:
curl [options] [URL]
-X, --request METHOD
: Specify request method (GET, POST, PUT, DELETE, etc.)-H, --header LINE
: Add header to the request-d, --data DATA
: Send data in POST request-F, --form CONTENT
: Submit form data-u, --user USER:PASSWORD
: Server user and password-k, --insecure
: Allow insecure server connections-I, --head
: Show document info only-v, --verbose
: Make the operation more verbose-s, --silent
: Silent mode--connect-timeout SECONDS
: Maximum time for connectionเครื่องมือแปลง Go ของเราจัดการคำสั่ง curl ที่ซับซ้อนรวมถึงหลาย headers, การตรวจสอบสิทธิ์, ข้อมูลที่ส่ง และตัวเลือกต่างๆ เพียงวางคำสั่ง curl ของคุณและรับโค้ด Go ที่สะอาดและทันสมัยโดยใช้แพ็คเกจ net/http
เมื่อทำงานกับแพ็คเกจ 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
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 }
// 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...
// 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)