golang现代化REST/GraphQL API开发框架插件Huma的使用

Golang现代化REST/GraphQL API开发框架插件Huma的使用

什么是Huma?

Huma是一个现代化、简单、快速且灵活的微框架,用于在Go中构建HTTP REST/RPC API,基于OpenAPI 3和JSON Schema。它的目标是提供:

  • 逐步采用现有服务的团队
  • 现代REST或HTTP RPC API后端框架
  • 防止常见错误的防护措施
  • 不会过时的文档
  • 高质量生成的开发者工具

Huma Logo

安装Huma

使用go get安装。注意需要Go 1.23或更新版本。

# After: go mod init ...
go get -u github.com/danielgtaylor/huma/v2

完整示例代码

以下是使用Huma构建"Hello World" API的完整示例:

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humachi"
	"github.com/danielgtaylor/huma/v2/humacli"
	"github.com/go-chi/chi/v5"

	_ "github.com/danielgtaylor/huma/v2/formats/cbor"
)

// Options for the CLI. Pass `--port` or set the `SERVICE_PORT` env var.
type Options struct {
	Port int `help:"Port to listen on" short:"p" default:"8888"`
}

// GreetingOutput represents the greeting operation response.
type GreetingOutput struct {
	Body struct {
		Message string `json:"message" example:"Hello, world!" doc:"Greeting message"`
	}
}

func main() {
	// Create a CLI app which takes a port option.
	cli := humacli.New(func(hooks humacli.Hooks, options *Options) {
		// Create a new router & API
		router := chi.NewMux()
		api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))

		// Add the operation handler to the API.
		huma.Get(api, "/greeting/{name}", func(ctx context.Context, input *struct{
			Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"`
		}) (*GreetingOutput, error) {
			resp := &GreetingOutput{}
			resp.Body.Message = fmt.Sprintf("Hello, %s!", input.Name)
			return resp, nil
		})

		// Tell the CLI how to start your router.
		hooks.OnStart(func() {
			http.ListenAndServe(fmt.Sprintf(":%d", options.Port), router)
		})
	})

	// Run the CLI. When passed no commands, it starts the server.
	cli.Run()
}

你可以使用go run greet.go运行这个示例(可选地通过--port参数改变默认端口),并使用Restish或curl进行测试:

# Get the message from the server
$ restish :8888/greeting/world
HTTP/1.1 200 OK
...
{
	$schema: "http://localhost:8888/schemas/GreetingOutputBody.json",
	message: "Hello, world!"
}

主要特性

  • 在你选择的路由器上的声明式接口
  • 使用RFC9457的JSON错误
  • 每个操作的请求大小限制
  • 服务器和客户端之间的内容协商
  • 条件请求支持
  • 自动生成PATCH操作
  • 输入和输出模型的注释Go类型
  • 使用Stoplight Elements生成文档
  • 内置可选CLI
  • 生成OpenAPI以访问丰富的工具生态系统
  • 生成JSON Schema

文档

完整的文档可以在Huma网站上找到。官方Go包文档可以在pkg.go.dev上找到。

评价

“这是我最喜欢的Go web框架。它受到FastAPI的启发,FastAPI也很棒,并且符合许多常见的Web RFC…我真的很喜欢它的功能集,它可以使用Chi的事实,以及它仍然相对简单的事实。” - Jeb_Jenky

“在使用Golang一年多后,我偶然发现了Huma,这个受FastAPI启发的web框架。这是我一直在期待的圣诞奇迹!这个框架拥有一切!” - Hana Mohan

“我爱Huma。真诚地感谢这个很棒的包。我已经使用它一段时间了,它很棒!” - plscott


更多关于golang现代化REST/GraphQL API开发框架插件Huma的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang现代化REST/GraphQL API开发框架插件Huma的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Huma框架:现代化REST/GraphQL API开发框架

Huma是一个现代化的Go语言API开发框架,专注于简化REST和GraphQL API的创建过程。它结合了高性能和开发效率,提供了许多开箱即用的功能。

Huma核心特性

  1. 同时支持REST和GraphQL
  2. 自动OpenAPI/Swagger文档生成
  3. 内置验证和序列化
  4. 高性能路由
  5. 简洁的API设计

安装Huma

go get github.com/danielgtaylor/huma/v2

基本REST API示例

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/adapters/humagin"
	"github.com/gin-gonic/gin"
)

// 定义输入模型
type GreetingInput struct {
	Name string `path:"name" maxLength:"30" example:"world" doc:"Name to greet"`
}

// 定义响应模型
type GreetingResponse struct {
	Message string `json:"message" example:"Hello, world!"`
}

func main() {
	// 创建路由
	router := gin.New()
	
	// 创建Huma API实例
	api := humagin.New(router, huma.DefaultConfig("My API", "1.0.0"))

	// 注册路由
	huma.Register(api, huma.Operation{
		OperationID: "get-greeting",
		Method:      http.MethodGet,
		Path:        "/greet/{name}",
		Summary:     "Get a greeting",
		Description: "Get a personalized greeting for the given name.",
	}, func(ctx context.Context, input *GreetingInput) (*GreetingResponse, error) {
		resp := &GreetingResponse{
			Message: fmt.Sprintf("Hello, %s!", input.Name),
		}
		return resp, nil
	})

	// 启动服务器
	http.ListenAndServe(":8888", router)
}

GraphQL支持示例

Huma也提供了GraphQL支持:

package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/danielgtaylor/huma/v2/graphql"
	"github.com/danielgtaylor/huma/v2/adapters/humagin"
	"github.com/gin-gonic/gin"
)

type Todo struct {
	ID    string `json:"id"`
	Title string `json:"title"`
	Done  bool   `json:"done"`
}

var todos = []Todo{
	{ID: "1", Title: "Buy milk", Done: false},
	{ID: "2", Title: "Walk dog", Done: true},
}

func main() {
	router := gin.New()
	api := humagin.New(router, huma.DefaultConfig("Todo API", "1.0.0"))

	// 注册GraphQL处理器
	graphqlHandler := graphql.NewHandler(api)
	
	// 添加GraphQL路由
	api.AddHandler(huma.Operation{
		Method: http.MethodPost,
		Path:   "/graphql",
	}, graphqlHandler)

	// 定义GraphQL查询
	graphqlHandler.Register(
		graphql.Query("todos", "Get all todos", func(ctx context.Context) ([]Todo, error) {
			return todos, nil
		}),
		graphql.Query("todo", "Get a todo by ID", func(ctx context.Context, args struct {
			ID string `graphql:"id"`
		}) (*Todo, error) {
			for _, todo := range todos {
				if todo.ID == args.ID {
					return &todo, nil
				}
			}
			return nil, fmt.Errorf("todo not found")
		}),
	)

	http.ListenAndServe(":8888", router)
}

高级功能

中间件支持

func LoggerMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		next.ServeHTTP(w, r)
		duration := time.Since(start)
		log.Printf("%s %s took %v", r.Method, r.URL.Path, duration)
	})
}

func main() {
	router := gin.New()
	api := humagin.New(router, huma.DefaultConfig("My API", "1.0.0"))
	
	// 添加中间件
	api.UseMiddleware(LoggerMiddleware)
	
	// ...注册路由等
}

验证器

Huma内置了强大的验证功能:

type CreateUserInput struct {
	Body struct {
		Username string `json:"username" minLength:"3" maxLength:"20" pattern:"^[a-zA-Z0-9]+$"`
		Email    string `json:"email" format:"email"`
		Age      int    `json:"age" minimum:"18" maximum:"120"`
	}
}

huma.Register(api, huma.Operation{
	OperationID: "create-user",
	Method:      http.MethodPost,
	Path:        "/users",
}, func(ctx context.Context, input *CreateUserInput) (*huma.NoResponse, error) {
	// 输入会自动验证
	// 处理逻辑...
	return nil, nil
})

自动文档

Huma会自动生成OpenAPI文档,可通过以下端点访问:

  • /openapi.json - OpenAPI规范JSON
  • /docs - 交互式API文档界面

性能考虑

Huma在性能方面做了优化:

  1. 使用高效的路由实现
  2. 零或最小化的反射使用
  3. 智能的序列化/反序列化
  4. 内置缓存机制

总结

Huma框架为Go开发者提供了创建现代化API的完整解决方案,主要优势包括:

  • 简洁直观的API设计
  • 同时支持REST和GraphQL
  • 自动化的文档生成
  • 内置验证和序列化
  • 良好的性能特性

对于需要快速开发高质量API的项目,Huma是一个值得考虑的选择。它特别适合需要同时提供REST和GraphQL接口,或者需要自动生成API文档的场景。

回到顶部