Migration to Hertz

Hertz provides the ability to migrate from other frameworks (FastHTTP, Gin) to Hertz.

Migration Script

The Hertz-contrib repository provides migration scripts for transferring other frameworks (FastHTTP, Gin) to Hertz. The specific usage is as follows:

cd your_project_path
sh -c "$(curl -fsSL https://raw.github.com/hertz-contrib/migrate/main/migrate.sh)"

After the script processing, a small portion may still require manual migration. Migration Tip: For example, if you need to modify the API for the header, which is located in the request (or response), in Hertz, the corresponding API is ctx.Request.Header.XXX() and other APIs follow a similar pattern. To make it easier for users to use, Hertz has also added commonly used APIs to ctx, such as using ctx.Body to obtain the body, instead of using ctx.Request.Body().

FastHTTP

Handler Function

// fasthttp request handler
type RequestHandler = func(ctx *fasthttp.RequestCtx)

// the corresponding Hertz request handler
type HandlerFunc = func(c context.Context, ctx *app.RequestContext)

UserValue

  • Hertz provides two interfaces, RequestContext.Keys and context.Value, for storing UserValue. RequestContext.Keys is used within a request and will be recycled when the request is completed, while context.Value will not be recycled when the request is completed and can be used in asynchronous scenarios such as logging and coroutines.

  • In fasthttp, Value and UserValue are equivalent, but in Hertz, RequestContext.Keys and context.Value correspond to different interfaces and have different data.

Router

  • Hertz provides a complete and efficient routing system and offers the ctx.Param method to retrieve routing parameters.

  • Example as follows:

// fasthttp + fasthttp router example
func Hello(ctx *fasthttp.RequestCtx) {
        fmt.Fprintf(ctx, "Hello, %s!\n", ctx.UserValue("name"))
}

func main() {
        r := router.New()
        r.GET("/hello/{name}", Hello)

        ...
}
// the corresponding hertz example
func Hello(c context.Context, ctx *app.RequestContext) {
        fmt.Fprintf(ctx, "Hello, %s!\n", ctx.Param("name"))
}

func main() {
        r := server.Default()
        r.GET("/hello/:name", Hello)

        ...
}

ListenAndServe

// fasthttp ListenAndServe
func main() {
    ...

    fasthttp.ListenAndServe(":8080", myHandler)
}
// Hertz example
func main() {
     r := server.Default(server.WithHostPorts(":8080"))

     ...

     r.Spin()
}

Gin

Handler Function

// Gin request handler
type RequestHandler = func(ctx *gin.Context)

// the corresponding Hertz request handler
type HandlerFunc = func(c context.Context, ctx *app.RequestContext)

Parameter Binding

  • Hertz currently only supports binding all data with ‘Bind’, and does not support binding data separately in Query or Body. For more details, please refer to Binding and Validation.

Set Response Data

  • Hertz supports setting the Response’s Header and Body in any order, unlike Gin which requires setting the Header first before setting the Body.
  • Example as follows:
// The example is valid on Hertz
func Hello(c context.Context, ctx *app.RequestContext) {
        // First, Set a body
        fmt.Fprintf(ctx, "Hello, World\n")

        // Then, Set a Header
        ctx.Header("Hertz", "test")
}

ListenAndServe

// Gin Run or use http.Server
func main() {
    r := gin.Default()

    ...

    r.Run(":8080")

    // or use http.Server
    srv := &http.Server{
        Addr:    ":8080",
        Handler: r,
    }
}
// Hertz example
func main() {
     r := server.Default(server.WithHostPorts(":8080"))

     ...

     r.Spin()
}

Appendix