Tạo một HTTP requests trong Golang

Spread the love

Yêu cầu HTTP là một phần rất cơ bản của web nói chung. Chúng được sử dụng để truy cập các tài nguyên được lưu trữ trên một máy chủ (có thể là từ xa).

HTTP là từ viết tắt của giao thức truyền siêu văn bản, một giao thức truyền thông đảm bảo việc truyền dữ liệu giữa máy khách và máy chủ. Một trường hợp hoàn hảo của tương tác máy khách-máy chủ HTTP là khi bạn mở trình duyệt của mình và nhập URL. Trình duyệt của bạn hoạt động như một máy khách và tìm nạp tài nguyên từ máy chủ mà sau đó nó sẽ hiển thị.

Trong phát triển web, các trường hợp chúng ta cần tìm nạp tài nguyên là rất phổ biến. Bạn có thể đang tạo một ứng dụng thời tiết và cần tìm nạp dữ liệu thời tiết từ một API. Trong trường hợp như vậy, việc sử dụng trình duyệt của bạn với tư cách là một ứng dụng khách sẽ không còn khả thi từ bên trong ứng dụng của bạn. Vì vậy, bạn phải thiết lập một ứng dụng khách HTTP trong ứng dụng của mình để xử lý việc thực hiện các yêu cầu này.

Hầu hết các ngôn ngữ lập trình đều có các cấu trúc khác nhau để thiết lập các máy khách HTTP để thực hiện các yêu cầu. Trong các phần tới, chúng ta sẽ thực hiện một cách tiếp cận thực tế để khám phá cách bạn có thể thực hiện các yêu cầu HTTP trong Golang hoặc Go, vì tôi sẽ đề cập đến ngôn ngữ trong phần còn lại của bài viết.

Điều kiện tiên quyết

Để theo dõi bài viết này, bạn sẽ cần:

Tạo một request HTTP trong Golang

GET request

Yêu cầu đầu tiên mà chúng tôi sẽ thực hiện là yêu cầu GET. Phương thức HTTP GET được sử dụng để yêu cầu dữ liệu từ một nguồn hoặc máy chủ được chỉ định. Phương thức GET chủ yếu được sử dụng khi dữ liệu cần được tìm nạp.

Để rõ ràng, điều quan trọng cần lưu ý là các phương thức HTTP, như được thấy trong bài viết này, luôn được viết hoa.

Đối với ví dụ của chúng tôi, chúng tôi sẽ tìm nạp một số dữ liệu JSON mẫu từ https://jsonplaceholder.typicode.com/comments bằng phương thức GET.

Bước đầu tiên để thực hiện một yêu cầu HTTP với Go là nhập gói net / http từ thư viện chuẩn. Gói này cung cấp cho chúng tôi tất cả các tiện ích mà chúng tôi cần để thực hiện các yêu cầu HTTP một cách dễ dàng. Chúng tôi có thể nhập gói net / http và các gói khác mà chúng tôi sẽ cần bằng cách thêm các dòng mã sau vào tệp main.go mà chúng tôi tạo:

import (
   "io/ioutil"
   "log"
   "net/http"
)

Gói net / http mà chúng tôi đã sử dụng có chức năng GET được sử dụng để thực hiện các GET request. Hàm Get nhận vào một URL và trả về một phản hồi của con trỏ kiểu cho một cấu trúc và một lỗi. Khi lỗi bằng nil, phản hồi được trả về sẽ chứa nội dung lỗi và ngược lại:

resp, err := http.Get("https://jsonplaceholder.typicode.com/comments")
if err != nil {
   log.Fatalln(err)
}

Để thực hiện yêu cầu, chúng tôi gọi hàm Get, truyền vào một chuỗi URL (https://jsonplaceholder.typicode.com/comments) như đã thấy ở trên. Các giá trị trả về từ lệnh gọi của hàm này được lưu trữ trong hai biến thường được gọi là resp và err. Mặc dù biến resp có chứa phản hồi của chúng tôi, nhưng nếu chúng tôi in nó ra, chúng tôi sẽ nhận được một lượng dữ liệu không mạch lạc bao gồm tiêu đề và các thuộc tính của yêu cầu được thực hiện. Để nhận được phản hồi mà chúng tôi quan tâm, chúng tôi phải truy cập thuộc tính Body trên cấu trúc phản hồi và đọc nó trước khi in nó ra Terminal. Chúng ta có thể đọc phần nội dung phản hồi bằng cách sử dụng hàm ioutil.ReadMe.

Tương tự như hàm Get, hàm ioutil.ReadMe trả về một nội dung và một lỗi. Điều quan trọng cần lưu ý là phần Body phản hồi phải được đóng lại sau khi chúng ta đọc xong phần này để tránh rò rỉ bộ nhớ.

Từ khóa defer thực thi resp.Body.Close() ở cuối hàm được sử dụng để đóng phần nội dung phản hồi. Sau đó, chúng ta có thể tiếp tục và in ra giá trị của phản hồi tới thiết bị đầu cuối. Là những lập trình viên giỏi, điều quan trọng là phải xử lý các lỗi có thể xảy ra, vì vậy chúng tôi sử dụng câu lệnh if để kiểm tra bất kỳ lỗi nào và ghi lại lỗi nếu nó tồn tại:

package main

import (
   "io/ioutil"
   "log"
   "net/http"
)

func main() {
   resp, err := http.Get("https://jsonplaceholder.typicode.com/comments")
   if err != nil {
      log.Fatalln(err)
   }

   body, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatalln(err)
   }

   sb := string(body)
   log.Printf(sb)
}

Tại thời điểm này, tất cả chúng ta đã sẵn sàng và có thể thực thi tệp chứa mã của chúng ta. Nếu mọi thứ suôn sẻ, bạn sẽ nhận thấy một số dữ liệu JSON tương tự như hình ảnh bên dưới được in ra terminal:

Xin chúc mừng, bạn vừa thực hiện yêu cầu HTTP đầu tiên của mình với Go. Bây giờ, chúng ta đã thấy cách chúng ta có thể tìm nạp tài nguyên từ máy chủ bằng phương thức HTTP GET, tiếp theo chúng ta sẽ xem xét cách đăng tài nguyên lên máy chủ.

POST request

Phương thức HTTP POST được sử dụng để thực hiện các yêu cầu thường chứa phần thân. Nó được sử dụng để gửi dữ liệu đến một máy chủ, dữ liệu được gửi đi thường được sử dụng để tạo hoặc cập nhật tài nguyên.

Một ví dụ rõ ràng trong đó yêu cầu POST được sử dụng là khi người dùng cố gắng tạo tài khoản mạng xã hội, người dùng được yêu cầu cung cấp dữ liệu của họ (tên, email và mật khẩu). Dữ liệu này sau đó được phân tích cú pháp và gửi dưới dạng yêu cầu POST tới máy chủ, máy chủ này sau đó sẽ tạo và lưu người dùng. Cũng giống như đối với phương pháp GET đã thấy ở trên, gói net / http của Go cũng cung cấp chức năng để thực hiện các yêu cầu POST thông qua chức năng POST. Hàm POST nhận ba tham số.

  1. Địa chỉ URL của máy chủ
  2. Loại nội dung của phần thân dưới dạng chuỗi
  3. Nôi dung yêu cầu sẽ được gửi bằng phương thức POST của loại io.Reader

Hàm Post trả về một phản hồi và một lỗi. Để chúng tôi gọi hàm POST, chúng tôi phải chuyển đổi phần thân yêu cầu của chúng tôi thành loại được chấp nhận. Đối với ví dụ này, chúng tôi sẽ thực hiện một yêu cầu đăng bài tới https://postman-echo.com/post và chuyển vào dữ liệu JSON có chứa tên và email. Để bắt đầu, chúng tôi chuyển đổi dữ liệu JSON của mình thành một kiểu triển khai giao diện Io.Reader mà hàm POST mong đợi, đây là một bước hai chiều:

  • Bước đầu tiên là mã hóa dữ liệu JSON của chúng tôi để nó có thể trả về dữ liệu ở định dạng byte, để thực hiện việc này, chúng tôi sử dụng hàm Marshall mà gói Go Json cung cấp
  • Tiếp theo, chúng tôi chuyển đổi dữ liệu JSON được mã hóa thành một kiểu được thực hiện bởi io.Reader, chúng tôi chỉ cần sử dụng hàm NewBuffer cho việc này, truyền dữ liệu JSON được mã hóa làm đối số. Hàm NewBuffer trả về một giá trị của bộ đệm kiểu mà sau đó chúng ta có thể chuyển cho hàm POST
postBody, _ := json.Marshal(map[string]string{
   "name":  "Toby",
   "email": "Toby@example.com",
})
responseBody := bytes.NewBuffer(postBody)

Bây giờ chúng ta có tất cả các đối số mà hàm POST yêu cầu, chúng ta có thể tiếp tục và gọi nó, chuyển vào https://postman-echo.com/post dưới dạng chuỗi URL, ứng dụng / JSON làm loại nội dung và nội dung yêu cầu được trả về bởi hàm NewBuffer làm phần thân. Sau đó, các giá trị được trả về bởi hàm POST được gán cho lần lượt là resp và err đại diện cho phản hồi và lỗi. Sau khi xử lý lỗi, chúng tôi đọc và in trong phần nội dung phản hồi như chúng tôi đã làm đối với hàm GET trong phần trước. Tại thời điểm này, tệp của bạn sẽ trông như thế này:

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

func main() {
   postBody, _ := json.Marshal(map[string]string{
      "name":  "Toby",
      "email": "Toby@example.com",
   })
   responseBody := bytes.NewBuffer(postBody)

   resp, err := http.Post("https://postman-echo.com/posts", "application/json", responseBody)
   if err != nil {
      log.Fatalf("An Error Occured %v", err)
   }
   defer resp.Body.Close()

   body, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatalln(err)
   }
   sb := string(body)
   log.Printf(sb)
}

Khi tệp được thực thi, nếu mọi thứ hoạt động tốt, chúng ta sẽ in phản hồi ra. Thật tuyệt vời, phải không? Chúng tôi vừa thực hiện một yêu cầu POST với Go bằng cách sử dụng gói net / http, gói này cung cấp chức năng giúp các yêu cầu HTTP dễ dàng hơn.

Trong những bài viết tiếp theo, chúng ta sẽ làm việc trên một dự án, để giúp chúng ta thấy các yêu cầu HTTP đang được sử dụng trong một kịch bản thực tế.

1 thought on “Tạo một HTTP requests trong Golang”

Leave a Comment