golang基于JSON API错误规范的错误处理插件库jsonapi-errors的使用

Golang基于JSON API错误规范的错误处理插件库jsonapi-errors的使用

简介

jsonapi-errors是一个遵循JSON API错误规范的Golang错误处理库。它提供了ErrorBag两个主要结构体,用于构建符合JSON API标准的错误响应。

基本使用

单个错误处理

package main

import (
	"encoding/json"
	"github.com/AmuzaTkts/jsonapi-errors"
)

func main() {
	// 创建一个包含单个错误的错误包
	bag := jsonapi_errors.NewBagWithError(502, "Oops =(")
	
	// 将错误包转换为JSON字符串
	jsonStr, _ := json.Marshal(bag)
	
	// jsonStr输出结果:
	// {
	//   "errors": [
	//     {
	//       "detail": "Oops =(",
	//       "status": "502"
	//     }
	//   ],
	//   "status": "502"
	// }
}

多个错误处理

相同错误类别的多个错误

package main

import (
	"encoding/json"
	"github.com/AmuzaTkts/jsonapi-errors"
)

func main() {
	// 创建一个空错误包
	bag := jsonapi_errors.NewBag()
	
	// 添加多个同类别错误(5xx服务器错误)
	bag.AddError(501, "Server Error 1")
	bag.AddError(502, "Server Error 2")
	
	// 将错误包转换为JSON字符串
	jsonStr, _ := json.Marshal(bag)
	
	// jsonStr输出结果:
	// {
	//   "errors": [
	//     {
	//       "detail": "Server Error 1",
	//       "status": "501"
	//     },
	//     {
	//       "detail": "Server Error 2",
	//       "status": "502"
	//     }
	//   ],
	//   "status": "500"  // 自动归为5xx类错误
	// }
}

不同错误类别的多个错误

package main

import (
	"encoding/json"
	"github.com/AmuzaTkts/jsonapi-errors"
)

func main() {
	// 创建一个空错误包
	bag := jsonapi_errors.NewBag()
	
	// 添加不同类别的错误
	bag.AddError(401, "Client Error 1") // 4xx客户端错误
	bag.AddError(502, "Server Error 1") // 5xx服务器错误
	
	// 将错误包转换为JSON字符串
	jsonStr, _ := json.Marshal(bag)
	
	// jsonStr输出结果:
	// {
	//   "errors": [
	//     {
	//       "detail": "Client Error 1",
	//       "status": "401"
	//     },
	//     {
	//       "detail": "Server Error 1",
	//       "status": "502"
	//     }
	//   ],
	//   "status": "400"  // 自动归为4xx类错误
	// }
}

特性说明

  1. 自动错误分类:当添加多个错误时,库会自动根据HTTP状态码范围确定主状态码

    • 4xx错误(400-499)表示客户端错误
    • 5xx错误(500-599)表示服务器错误
    • 混合错误时优先返回4xx状态码
  2. 符合JSON API规范:生成的错误响应完全遵循JSON API错误格式标准

  3. 简单易用:只需提供状态码和错误信息即可生成标准化的错误响应

这个库非常适合需要遵循JSON API规范的RESTful API开发,可以轻松构建标准化的错误响应。


更多关于golang基于JSON API错误规范的错误处理插件库jsonapi-errors的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang基于JSON API错误规范的错误处理插件库jsonapi-errors的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang JSON API 错误处理插件库 jsonapi-errors 使用指南

jsonapi-errors 是一个遵循 JSON API 错误规范的 Golang 错误处理库,它可以帮助开发者构建符合规范的 API 错误响应。

安装

go get github.com/AmuzaTkts/jsonapi-errors

基本使用

1. 创建错误

package main

import (
	"encoding/json"
	"fmt"
	"github.com/AmuzaTkts/jsonapi-errors"
	"net/http"
)

func main() {
	// 创建一个基础错误
	err := jsonapi_errors.New().
		SetStatus(http.StatusBadRequest).
		SetTitle("Invalid Attribute").
		SetDetail("The 'email' attribute is invalid").
		SetCode("invalid_email").
		SetSourcePointer("/data/attributes/email")
	
	// 转换为JSON
	jsonData, _ := json.MarshalIndent(err, "", "  ")
	fmt.Println(string(jsonData))
}

输出结果:

{
  "errors": [
    {
      "status": "400",
      "title": "Invalid Attribute",
      "detail": "The 'email' attribute is invalid",
      "code": "invalid_email",
      "source": {
        "pointer": "/data/attributes/email"
      }
    }
  ]
}

2. 多个错误处理

func handleMultipleErrors() {
	errs := jsonapi_errors.New().
		AddError(
			jsonapi_errors.New().
				SetStatus(http.StatusBadRequest).
				SetTitle("Invalid Email").
				SetDetail("Email format is invalid").
				SetSourcePointer("/data/attributes/email"),
		).
		AddError(
			jsonapi_errors.New().
				SetStatus(http.StatusBadRequest).
				SetTitle("Missing Password").
				SetDetail("Password is required").
				SetSourcePointer("/data/attributes/password"),
		)
	
	jsonData, _ := json.MarshalIndent(errs, "", "  ")
	fmt.Println(string(jsonData))
}

3. 与 HTTP 处理器集成

func handler(w http.ResponseWriter, r *http.Request) {
	// 模拟验证失败
	if r.URL.Query().Get("token") == "" {
		err := jsonapi_errors.New().
			SetStatus(http.StatusUnauthorized).
			SetTitle("Unauthorized").
			SetDetail("Missing authentication token").
			SetCode("missing_token")
		
		w.Header().Set("Content-Type", "application/vnd.api+json")
		w.WriteHeader(err.Status())
		json.NewEncoder(w).Encode(err)
		return
	}
	
	// 正常处理逻辑
	w.Write([]byte("OK"))
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

4. 自定义错误类型

type CustomError struct {
	*jsonapi_errors.Error
}

func NewCustomError() *CustomError {
	return &CustomError{
		Error: jsonapi_errors.New(),
	}
}

func (e *CustomError) SetValidationError(field, message string) *CustomError {
	e.SetStatus(http.StatusBadRequest).
		SetTitle("Validation Error").
		SetDetail(message).
		SetSourcePointer(fmt.Sprintf("/data/attributes/%s", field)).
		SetCode("validation_error")
	return e
}

func main() {
	err := NewCustomError().
		SetValidationError("username", "Username must be at least 6 characters")
	
	jsonData, _ := json.MarshalIndent(err, "", "  ")
	fmt.Println(string(jsonData))
}

高级特性

1. 错误元数据

err := jsonapi_errors.New().
	SetStatus(http.StatusTooManyRequests).
	SetTitle("Rate Limit Exceeded").
	SetDetail("You have exceeded your API rate limit").
	SetMeta(map[string]interface{}{
		"limit":     100,
		"remaining": 0,
		"reset":     "2023-01-01T00:00:00Z",
	})

2. 错误链接

err := jsonapi_errors.New().
	SetStatus(http.StatusNotFound).
	SetTitle("Resource Not Found").
	SetDetail("The requested resource was not found").
	SetLinks(map[string]string{
		"about": "https://api.example.com/docs/errors/not_found",
	})

3. 从标准错误转换

func fromStdError(stdErr error) *jsonapi_errors.Errors {
	return jsonapi_errors.New().
		AddError(
			jsonapi_errors.New().
				SetStatus(http.StatusInternalServerError).
				SetTitle("Internal Server Error").
				SetDetail(stdErr.Error()),
		)
}

最佳实践

  1. 始终设置状态码:确保每个错误都有对应的 HTTP 状态码
  2. 提供有用的详情:错误详情应该帮助客户端开发者理解问题
  3. 使用错误代码:定义可编程的错误代码便于客户端处理
  4. 指明错误来源:对于验证错误,使用指针指明具体字段
  5. 保持一致性:在整个 API 中使用相同的错误结构和格式

jsonapi-errors 库简化了符合 JSON API 规范的错误处理,使得构建一致且有用的 API 错误响应变得更加容易。通过其流畅的 API,开发者可以快速构建复杂的错误响应,同时保持代码的清晰和可维护性。

回到顶部