ارسال درخواست HTTP برای هر برنامه ای که نیاز به برقراری ارتباط از طریق اینترنت دارد، کلیدی است. نحوه ارسال انواع درخواست های HTTP با استفاده از Go را بیاموزید.
یکی از اصول اساسی که بر عملکرد شبکه جهانی وب حاکم است، تبادل درخواست ها و پاسخ ها است. هنگامی که درخواستی برای دسترسی به یک صفحه وب ارسال می کنید، سرور با داده های مناسب پاسخ می دهد.
پروتکل های معروفی که انواع مختلف ارتباطات اینترنتی را کنترل می کنند عبارتند از HTTP (پروتکل انتقال ابرمتن)، FTP (پروتکل انتقال فایل) و SMTP (پروتکل انتقال ایمیل ساده).
HTTP پروتکلی است که معمولاً هنگام مشاهده یک وب سایت یا استفاده از یک برنامه فعال شده تحت وب از آن استفاده می کنید. همچنین می توانید با درخواست های HTTP بسیاری از زبان های برنامه نویسی از جمله Go کار کنید.
درخواست HTTP چیست؟
HTTP تعریف میکند که چگونه کلاینتها، مانند مرورگرهای وب، درخواستهایی را به سرورها ارسال میکنند و سپس پاسخی را برمیگردانند. یک درخواست HTTP حاوی اطلاعاتی در مورد منبعی است که مشتری سعی دارد به آن دسترسی پیدا کند. پیام درخواست معمولاً شامل یک URL است که منبع و سایر داده های اختیاری مانند سرصفحه ها و پارامترهای پرس و جو را شناسایی می کند.
انواع مختلفی از درخواست HTTP وجود دارد، از جمله GET، POST، PUT، DELETE، HEAD، OPTIONS و CONNECT. چهار نوع روش اول رایج ترین هستند. آنها عملیات CRUD را به ترتیب خواندن، ایجاد، به روز رسانی و حذف منعکس می کنند.
نوع درخواست PUT اغلب به جای نوع درخواست PATCH استفاده می شود. آنها به همان هدف می رسند، آنها فقط در داده هایی که انتظار دارند درخواست شامل شود با هم تفاوت دارند.
ارسال درخواست ها با استفاده از روش های رایج HTTP
بسته http داخلی Go مجموعه ای از توابع و ساختارها را ارائه می دهد که می توانید از آنها برای ایجاد سرورهای وب و مدیریت درخواست های HTTP استفاده کنید. این یک بسته بسیار قوی است و همه فریم ورک های وب Go به یک روش بر روی آن ساخته می شوند. این یک بسته فرعی از بسته نت Go است.
برای ایجاد یک درخواست HTTP در Go، میتوانید از تابع http.NewRequest() استفاده کنید و متد، URL، هدرها و بدنه درخواست مناسب را تنظیم کنید. پس از ایجاد درخواست، میتوانید از ساختار http.Client{} بسته Go net/http برای اجرای آن و دریافت پاسخ استفاده کنید.
نمونههای کد زیر از reqres.in، یک API در دسترس عموم برای آزمایش درخواستهای HTTP استفاده میکنند. میتوانید از آن برای آزمایش درخواستهای GET، POST، PUT و DELETE در برنامههای Go خود استفاده کنید.
درخواست ارسال
کد زیر تابعی است که یک درخواست POST را به /api/users endpoint reqres.in ارسال می کند تا یک کاربر جدید با نام و شغل ایجاد کند.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func createUser(name, job string) {
fmt.Println("Creating user...")
apiUrl := "https://reqres.in/api/users"
userData := []byte(`{"name":"` + name + `","job":"` + job + `"}`)
// create new http request
request, error := http.NewRequest("POST", apiUrl, bytes.NewBuffer(userData))
request.Header.Set("Content-Type", "application/json; charset=utf-8")
// send the request
client := &http.Client{}
response, error := client.Do(request)
if error != nil {
fmt.Println(error)
}
responseBody, error := io.ReadAll(response.Body)
if error != nil {
fmt.Println(error)
}
formattedData := formatJSON(responseBody)
fmt.Println("Status: ", response.Status)
fmt.Println("Response body: ", formattedData)
// clean up memory after execution
defer response.Body.Close()
}
formatJSON یک تابع سفارشی است که می توانید برای قالب بندی داده های خروجی بنویسید. در اینجا نحوه اجرای آن آمده است:
// function to format JSON data
func formatJSON(data []byte) string {
var out bytes.Buffer
err := json.Indent(&out, data, "", " ")
if err != nil {
fmt.Println(err)
}
d := out.Bytes()
return string(d)
}
میتوانید تابع createUser() را در برنامهای مانند این فراخوانی کنید:
func main() {
fmt.Println("Making POST request...")
createUser("Tim Omolana", "Writer")
}
هنگامی که برنامه را در یک ترمینال اجرا می کنید، با استفاده از دستور go run
دریافت درخواست
کد زیر تابعی است که یک درخواست GET برای بازیابی کاربر از سرور reqres.in با استفاده از شناسه منحصر به فرد خود ارسال می کند.
// main.go
func getUser(id string) {
fmt.Println("Getting user by ID...")
// make GET request to API to get user by ID
apiUrl := "https://reqres.in/api/users/" + id
request, error := http.NewRequest("GET", apiUrl, nil)
if error != nil {
fmt.Println(error)
}
request.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
response, error := client.Do(request)
if error != nil {
fmt.Println(error)
}
responseBody, error := io.ReadAll(response.Body)
if error != nil {
fmt.Println(error)
}
formattedData := formatJSON(responseBody)
fmt.Println("Status: ", response.Status)
fmt.Println("Response body: ", formattedData)
// clean up memory after execution
defer response.Body.Close()
}
درخواست GET دادهها را به سرور ارسال نمیکند، بنابراین درخواستی را نمیپذیرد یا زمانی که درخواست میشود به سرور ارسال میکند. در اینجا مثالی از فراخوانی تابع بالا به نظر می رسد:
func main() {
fmt.Println("Making GET request...")
getUser("2")
}
خروجی:
درخواست PUT
درخواست PUT بسیار شبیه به درخواست POST است زیرا داده ها را به سرور نیز ارسال می کند. تفاوت عمده این است که POST یک منبع جدید ایجاد می کند در حالی که PUT منبع موجود را به روز می کند.
در اینجا اجرای یک درخواست PUT آمده است:
// main.go
func updateUser(name, job, id string) {
fmt.Println("Updating user...")
// make PUT request to API to update user
apiUrl := "https://reqres.in/api/users/" + id
userData := []byte(`{"name":"` + name + `","job":"` + job + `"}`)
// create new http PUT request
request, error := http.NewRequest("PUT", apiUrl, bytes.NewBuffer(userData))
request.Header.Set("Content-Type", "application/json; charset=utf-8")
// Remaining function body from createUser function...
// Make request, get response, and clear memory...
}
از این کد، تنها تفاوت بین درخواست PUT و درخواست POST در بالا، نام روش و URL است. هنگام استفاده از PUT برای به روز رسانی داده های موجود، باید شناسه را به URL درخواست اضافه کنید. یک فراخوانی نمونه به این تابع به شکل زیر است:
func main() {
// update entry with the ID 2.
updateUser("Tim Newname", "Staff Writer", "2")
}
کد بالا کاربر را به روز می کند و خروجی زیر را تولید می کند:
درخواست حذف
از روش درخواست DELETE برای انجام عملیات حذف در وب سرور استفاده کنید. درخواست حذف، منبع شناسایی شده توسط URI را حذف می کند. یک درخواست DELETE در Go به این صورت است:
func deleteUser(id string) {
fmt.Println("Deleting user...")
// make DELETE request to API to delete user
apiUrl := "https://reqres.in/api/users/" + id
// create new http request
request, error := http.NewRequest("DELETE", apiUrl, nil)
request.Header.Set("Content-Type", "application/json; charset=utf-8")
client := &http.Client{}
response, error := client.Do(request)
if error != nil {
fmt.Println(error)
}
fmt.Println("Status: ", response.Status)
}
درخواست DELETE نه بدنه ای را می پذیرد و نه برمی گرداند، از این رو نیازی به تجزیه یا قالب بندی درخواست و پاسخ JSON نیست. پاسخ فقط وضعیتی را برای نشان دادن موفقیت یا شکست برمیگرداند. در اینجا نمونه ای از فراخوانی تابع با خروجی آن به نظر می رسد:
func main() {
fmt.Println("Making DELETE request...")
deleteUser("2")
}
خروجی:
با استفاده از متدهای http.Post() و http.Get() از بسته net/http برای ایجاد مستقیم درخواست های POST و GET، بدون نیاز به استفاده از تابع NewRequest() و ساختار Client{} برای ایجاد و ساخت، در زمان صرفه جویی کنید. درخواست به صورت جداگانه برای اطلاعات بیشتر، مستندات net/http را بررسی کنید.
ایجاد درخواست HTTP در برنامه های Go
بسته http در Go همه چیز مورد نیاز برای درخواست های HTTP و رسیدگی به پاسخ ها در برنامه های Go را فراهم می کند. توابع و ساختارهای ارائه شده توسط بسته شما را قادر می سازد تا انواع مختلفی از درخواست ها مانند GET، POST، PUT، DELETE و بسیاری دیگر را ایجاد و ارسال کنید.
این امر ساخت برنامه های وب را در Go آسان می کند که می توانند با سایر سرویس های وب و API ها تعامل داشته باشند. یک راه خوب برای آشنایی بیشتر با ایجاد درخواستهای HTTP در Go، ساختن برنامهای است که درخواستها را به یکی دیگر از APIهای REST شما ارسال میکند.