Chuyển đổi lệnh curl thành mã Go - Tạo mã Go net/http sẵn sàng sử dụng cho các yêu cầu 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)) }
Dưới đây là một số lệnh curl phổ biến mà bạn có thể chuyển đổi thành mã 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
Gói net/http của Go cung cấp một cách mạnh mẽ và hiệu quả để thực hiện các yêu cầu HTTP. Dưới đây là một số mẫu HTTP Go phổ biến:
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) }
Sao chép lệnh curl của bạn → Dán vào hộp nhập liệu → Nhận mã Go ngay lập tức
// 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 }
Đ: Trong khi curl là một công cụ dòng lệnh để thực hiện các yêu cầu HTTP, gói net/http của Go cung cấp một API lập trình. Go cung cấp kiểu dữ liệu mạnh hơn, hỗ trợ đồng thời tích hợp và tích hợp tốt hơn với mã ứng dụng của bạn, trong khi curl xuất sắc trong việc kiểm thử nhanh và kịch bản ad-hoc.
Đ: Go sử dụng defer resp.Body.Close() để đảm bảo tài nguyên được giải phóng đúng cách ngay cả khi lỗi xảy ra sau đó trong hàm. Mẫu này là thành ngữ trong Go và ngăn chặn rò rỉ tài nguyên có thể xảy ra nếu bạn quên đóng phần thân trong tất cả các đường dẫn mã có thể.
Đ: Thay vì sử dụng ioutil.ReadAll()
, bạn có thể xử lý phần thân phản hồi như một luồng bằng cách sử dụng io.Copy()
hoặc bằng cách đọc các phần với bộ đệm. Điều này đặc biệt hữu ích cho các phản hồi lớn mà việc tải toàn bộ phần thân vào bộ nhớ sẽ không hiệu quả.
Đ: Có, và điều này được khuyến nghị! Việc tạo một http.Client
duy nhất và tái sử dụng nó qua các yêu cầu cho phép gộp kết nối và cải thiện hiệu suất. Client an toàn cho đồng thời và có thể được chia sẻ giữa các goroutine mà không cần đồng bộ hóa bổ sung.
Đ: Gói context của Go cung cấp hủy yêu cầu thanh lịch. Tạo một context với context.WithCancel()
hoặc context.WithTimeout()
, sau đó truyền nó vào http.NewRequestWithContext()
. Bạn có thể hủy yêu cầu bất kỳ lúc nào bằng cách gọi hàm hủy.
Đ: Để bỏ qua xác minh chứng chỉ TLS (giống như cờ -k của curl), cấu hình một Transport tùy chỉnh trong HTTP client của bạn: client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}}
Tuy nhiên, điều này chỉ nên được sử dụng cho kiểm thử, vì nó bỏ qua các kiểm tra bảo mật.
Đ: HTTP client của Go tự động theo dõi chuyển hướng (tối đa 10 lần theo mặc định), tương tự như curl. Để tùy chỉnh hành vi này, đặt một hàm CheckRedirect
tùy chỉnh trong HTTP client của bạn để kiểm soát xử lý chuyển hướng hoặc ngăn chặn chuyển hướng hoàn toàn.
Hiểu các lệnh curl là điều cần thiết cho kiểm thử API Go hiệu quả. Dưới đây là tham khảo nhanh về các tùy chọn curl phổ biến mà bộ chuyển đổi của chúng tôi hỗ trợ:
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 connectionBộ chuyển đổi Go của chúng tôi xử lý các lệnh curl phức tạp bao gồm nhiều header, xác thực, tải trọng dữ liệu và các tùy chọn khác nhau. Chỉ cần dán lệnh curl của bạn và nhận mã Go sạch, hiện đại sử dụng gói net/http.
Khi làm việc với gói net/http của Go, hãy tuân theo các thực hành tốt nhất sau đây để tương tác API hiệu quả và an toàn:
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)