iT邦幫忙

2023 iThome 鐵人賽

DAY 22
1
Modern Web

起步Go!Let's Go!系列 第 22

[ Day 22 ] GO 創建簡單的用戶端:踏上與伺服器對話的征途

  • 分享至 

  • xImage
  •  

在現代應用程式中,用戶端和伺服器之間的通信是不可或缺的一部分。Go 的強項之一是其在構建網路應用程序方面的表現。今天,我們將深入研究如何使用 Go 語言創建一個簡單而強大的用戶端,使用戶端能夠透過 HTTP 協定與伺服器進行通信,而關於甚麼是 HTTP 協定,網上有很多相關的文章可以參考,今天我們將關注 HTTP Request 中的 GET、POST、PUT、DELETE 基本 HTTP 方法。

HTTP 請求方法

HTTP 定義了一些不同的請求方法,每種方法都有不同的目的和意義。以下是一些常見的 HTTP 方法:

  • GET: 取得資料,就像在瀏覽器中輸入網址查看網頁一樣。
  • POST: 提交資料,比如填寫一個註冊表單或上傳檔案。
  • PUT: 儲存資料,通常是更新已有的資源,比如修改雲端儲存中的檔案。
  • DELETE: 刪除資源,例如在郵箱中刪除郵件或在社交媒體上刪除貼文。
    這些請求方法的 URL 分別為:
方法 URL
GET https://example.com/
POST https://example.com/posts
PUT https://example.com/posts/225
DELETE https://example.com/posts/225

接下來,我會用以上的四種方法示範如何應用在 Go 程式中。

在 Go 發送 GET 請求

在 Go 中,我們可以使用昨天提到的net/http 套件,它可以方便地發送 HTTP 請求。
當需要發送 GET 請求時,可以使用 http.Get 這個函式以下是如何使用 Go 發送 GET 請求:

package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://jsonplaceholder.typicode.com/posts/1"

	response, err := http.Get(url)
	if err != nil {
		fmt.Print("err: ", err)
	}

	closer := response.Body
	bytes, err := io.ReadAll(closer)

	if err != nil {
		fmt.Println("Error reading response body:", err)
	}

	fmt.Println(string(bytes))
}

執行結果
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

依照上面這個程式我們可以輕鬆的得到 url 中的資料。
這邊提一下 https://jsonplaceholder.typicode.com 這個網站是一個為開發和測試而設計的假 JSON API 服務,所以當你要測試 JSON API 時就可以使用這個網站。是一個非常實用的工具。

在 Go 發送 POST 請求

當要使用 POST 請求時,我們可以使用 http.Post 這個函式來協助我們:

package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://jsonplaceholder.typicode.com/posts"

	payload := []byte(`{"title": "foo", "body": "bar", "userId": 1}`)
	response, err := http.Post(url, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		fmt.Println("POST request failed:", err)
		return
	}

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

	fmt.Println(string(body))
}

執行結果:
{
"title": "foo",
"body": "bar",
"userId": 1,
"id": 101
}

在 Go 發送 PUT 請求

發送 PUT 請求也不難,但是 PUT 並沒有被 GO 單獨封裝,所以只能用 httpNewRequest 來實現,如下:

package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://jsonplaceholder.typicode.com/posts/1"

	// 設定 PUT 請求的內容
	payload := []byte(`{"title": "foo", "body": "booodklasdh kldafukgew", "userId": 1}`)
	request, err := http.NewRequest("PUT", url, bytes.NewBuffer(payload))
	if err != nil {
		fmt.Println("Error creating PUT request:", err)
		return
	}

	// 設定請求的標頭
	request.Header.Set("Content-Type", "application/json")

	// 發送 PUT 請求
	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		fmt.Println("PUT request failed:", err)
		return
	}

	// 讀取回應的主體
	body, err := io.ReadAll(response.Body)
	if err != nil {
		fmt.Println("Error reading response body:", err)
		return
	}

	// 印出回應的內容
	fmt.Println(string(body))
}

執行結果
{
"title": "foo",
"body": "booodklasdh kldafukgew",
"userId": 1,
"id": 1
}

在 Go 發送 DELETE 請求

當我們要發送 DELETE 請求時,我們也可以使用 http.NewRequest 來做:

package main

import (
	"fmt"
	"net/http"
)

func main() {
	url := "https://jsonplaceholder.typicode.com/posts/1"

	// 建立 DELETE 請求
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		fmt.Println("Error creating DELETE request:", err)
		return
	}

	// 發送 DELETE 請求
	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		fmt.Println("DELETE request failed:", err)
		return
	}

	// 關閉回應的主體
	defer response.Body.Close()

	// 讀取回應的主體
	// 這裡可能會有特定的處理,例如確認是否刪除成功等

	fmt.Println("DELETE request successful")
}

執行結果
DELETE request successful

以上便是如何將 HTTP Request 應用在 Go 程式中的方法,這還只是開始,接下來還有更大的挑戰等著你!!
我們明天見。


上一篇
[ Day 21 ] Go HTTP 伺服器:啟航你的網路冒險之旅
下一篇
[ Day 23 ] Go 模板引擎:動態生成 HTML 頁面的魔法
系列文
起步Go!Let's Go!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言