Skip to content

介绍

Resty是用来发送 http 请求的工具包, 类似 JS 的 axios

运行一个服务端用来处理请求

go
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/gofiber/fiber/v3"
)

func main() {
	app := fiber.New()

	// 获取 Query
	app.Get("/query", func(c fiber.Ctx) error {
		keyword := c.Query("keyword")   // 获取查询关键字
		page := c.Query("page", "1")    // 获取查询页码
		limit := c.Query("limit", "10") // 获取每页查询个数限制

		return c.JSON(fiber.Map{
			"keyword": keyword,
			"page":    page,
			"limit":   limit,
		})
	})

	// 获取 form
	app.Post("/form", func(c fiber.Ctx) error {
		email := c.FormValue("email")       // 获取 form 中的 email 参数
		password := c.FormValue("password") // 获取 form 中的 password 参数

		return c.JSON(fiber.Map{
			"email":    email,
			"password": password,
		})
	})

	// 获取json
	app.Post("/json", func(c fiber.Ctx) error {
		// 绑定时验证数据
		type LoginFormDto struct {
			Email    string `json:"email" validate:"required,email"`
			Password string `json:"password" validate:"required,min=6"`
		}

		// 绑定数据
		loginForm := new(LoginFormDto)
		if err := c.Bind().JSON(loginForm); err != nil {
			return err
		}

		return c.JSON(fiber.Map{
			"message":  "login success",
			"email":    loginForm.Email,
			"password": loginForm.Password,
		})
	})

	// 文件上传
	app.Post("/upload", func(c fiber.Ctx) error {
		// 获取文件
		file, err := c.FormFile("file")
		if err != nil {
			fmt.Printf("获取文件失败: %v", err)
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
				"error": "无效的文件字段, 请确保使用 'file' 作为表单名",
			})
		}

		// 文件信息
		fmt.Println("文件名:", file.Filename)
		fmt.Println("文件大小:", file.Size)
		fmt.Println("文件类型:", file.Header.Get("Content-Type"))

		// 确保目录存在
		if err := os.MkdirAll("./uploads", 0o755); err != nil {
			fmt.Printf("创建 uploads 目录失败: %v", err)
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"error": "服务器内部错误",
			})
		}

		// 保存文件
		filePath := fmt.Sprintf("./uploads/%s", file.Filename)
		if err := c.SaveFile(file, filePath); err != nil {
			fmt.Printf("保存文件失败 %s: %v", filePath, err)
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
				"error": "文件保存失败",
			})
		}

		return c.JSON(fiber.Map{
			"message":  "上传成功",
			"filepath": "./uploads/" + file.Filename,
			"filename": file.Filename,
			"size":     file.Size,
		})
	})

	// 获取请求头
	app.Get("/header", func(c fiber.Ctx) error {
		headers := c.GetReqHeaders()
		accessToken := c.Get("Authorization")
		return c.JSON(fiber.Map{
			"headers":     headers,
			"accessToken": accessToken,
		})
	})


	// 响应一个附件下载
	app.Get("/download", func(c fiber.Ctx) error {
		return c.Download("./main.go")
	})

	if err := app.Listen(":3000"); err != nil {
		log.Fatal(err)
	}
}

安装

go
go get -u "github.com/gofiber/fiber/v3"

基本使用

go
package main

import (
	"fmt"

	"github.com/go-resty/resty/v2"
)

func Api(path string) string {
	return "http://127.0.0.1:3000" + path
}

// 发送get请求并携带 query 参数
func sendGetRequest() {
	client := resty.New()

	response, err := client.R().SetQueryParams(map[string]string{
		"keyword": "golang",
		"page":    "1",
		"limit":   "10",
	}).Get(Api("/query"))
	if err != nil {
		fmt.Println("Network error:", err)
		return
	}

	body := response.String()
	fmt.Println(body)
}

// 发送post请求并携带 form 参数
func sendPostRequestWithForm() {
	client := resty.New()
	response, err := client.R().SetFormData(map[string]string{
		"email":    "test@test.com",
		"password": "123456",
	}).Post(Api("/form"))
	if err != nil {
		fmt.Println("Network error:", err)
		return
	}

	body := response.String()
	fmt.Println(body)
}

// 发送post请求并携带 json 参数
func sendPostRequestWithJson() {
	client := resty.New()
	response, err := client.R().SetBody(map[string]string{
		"email":    "test@exmaple.com",
		"password": "123456",
	}).Post(Api("/json"))
	if err != nil {
		fmt.Println("Network error:", err)
		return
	}

	body := response.String()
	fmt.Println(body)
}

// 发送post请求并携带文件上传参数
func sendPostRequestWithUpload() {
	client := resty.New()
	localFilePath := "./files/avatar.png" // 确保这个文件存在
	response, err := client.R().SetFile("file", localFilePath).Post(Api("/upload"))
	if err != nil {
		fmt.Println("Network error:", err)
		return
	}

	body := response.String()
	fmt.Println(body)
}

// 发送post请求并携带haeder参数
func sendRequestWithHeader() {
	client := resty.New()
	response, err := client.R().SetHeader("Authorization", "mock-token-str").Get(Api("/header"))
	if err != nil {
		fmt.Println("Network error:", err)
		return
	}

	body := response.String()
	fmt.Println(body)
}

// 发送请求下载文件
func sendRequestForDownloadFile() {
	client := resty.New()
	outputFilePath := "./files/server.go"
	_, err := client.R().SetOutput(outputFilePath).Get(Api("/download"))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("下载成功")
}

func main() {
	// sendGetRequest()
	// sendPostRequestWithForm()
	// sendPostRequestWithJson()
	// sendPostRequestWithUpload()
	// sendRequestForDownloadFile()
	sendRequestWithHeader()
}

响应自动解析

所谓的自动解析就是将json数据解析为go语言的 struct

go
package main

import (
	"fmt"

	"github.com/go-resty/resty/v2"
)

type LoginResponse struct {
	Message  string `json:"message"`
	Email    string `json:"email"`
	Password string `json:"password"`
}

type LoginFormDto struct {
	Email    string `json:"email"`
	Password string `json:"password"`
}

func Api(path string) string {
	return "http://127.0.0.1:3000" + path
}

func main() {
	client := resty.New()

	loginForm := LoginFormDto{
		Email:    "test@example.com",
		Password: "123456",
	}

	rowResponse, _ := client.R().SetHeaders(map[string]string{
		"Content-Type": "application/json",
		"Accept":       "application/json",
	}).SetBody(loginForm).SetResult(&LoginResponse{}).Post(Api("/json"))

	// -> .Result() 方法自动解析 -> 断言为 LoginResponse 类型
	loginResponse := rowResponse.Result().(*LoginResponse)

	fmt.Println("Message", loginResponse.Message)
	fmt.Println("Email", loginResponse.Email)
	fmt.Println("Password", loginResponse.Password)
}

拦截器 interceptor

go
package main

import (
	"fmt"

	"github.com/go-resty/resty/v2"
)

func Api(path string) string {
	return "http://127.0.0.1:3000" + path
}

func main() {
	client := resty.New()

	client.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error {
		// 请求发出之前, 可以对请求信息做一些修改/获取
		fmt.Println("before request send:", r.URL)
		return nil
	})

	client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
		// 获取响应之后, 可以对响应信息做一些修改/获取
		fmt.Println("after response:", r.Status())
		return nil
	})

	client.OnError(func(r *resty.Request, e error) {
		// 发送请求发生错误时
		fmt.Println("get some error:", e)
	})

	reponse, _ := client.R().SetQueryParams(map[string]string{
		"keyword": "go",
		"page":    "10",
	}).Get(Api("/query"))

	result := reponse.String()
	fmt.Println("result:", result)
}

Released under the MIT License.