Labstack/echo: Difference between revisions
Jump to navigation
Jump to search
(10 intermediate revisions by the same user not shown) | |||
Line 43: | Line 43: | ||
=Registering Handlers Generated by oapi-codegen from an OpenAPI Specification= | =Registering Handlers Generated by oapi-codegen from an OpenAPI Specification= | ||
{{Internal|Oapi-codegen# | {{Internal|Oapi-codegen#Server_Code_Generation|<tt>oapi-codegen</tt> Server Code Generation}} | ||
<code>[[Oapi-codegen#Overview|oapi-codegen]]</code> generates a <code>ServerInterface</code> interface that exposes methods for [[OpenAPI_Specification_Path#Server_Code_Generation_for_Path/Operation_Combinations|each path/operation pair]] specified in the OpenAPI specification: | |||
<syntaxhighlight lang='go'> | |||
// ServerInterface represents all server handlers. | |||
type ServerInterface interface { | |||
// (GET /pets) | |||
GetPets(ctx echo.Context, params GetPetsParams) error | |||
// (POST /pets) | |||
CreatePet(ctx echo.Context) error | |||
... | |||
} | |||
</syntaxhighlight> | |||
Implement the <code>ServerInterface</code>: | |||
<syntaxhighlight lang='go'> | <syntaxhighlight lang='go'> | ||
type PetStoreServer struct { | type PetStoreServer struct { | ||
} | } | ||
Line 60: | Line 66: | ||
func (s *PetStoreServer) GetPets(ctx echo.Context, params petstore.GetPetsParams) error { | func (s *PetStoreServer) GetPets(ctx echo.Context, params petstore.GetPetsParams) error { | ||
... | |||
} | } | ||
func (s *PetStoreServer) CreatePet(ctx echo.Context) error { | |||
... | |||
} | |||
... | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Then instantiate an <code>echo</code> server and register the handlers: | |||
<syntaxhighlight lang='go'> | <syntaxhighlight lang='go'> | ||
s := NewPetStoreServer() | |||
e := echo.New() | |||
// Middleware | // Middleware | ||
e.Use(middleware.Logger()) | |||
e.Use(middleware.Recover()) | |||
// Routes | // Routes | ||
petstore.RegisterHandlers( | petstore.RegisterHandlers(e, s) | ||
// Start server | // Start server | ||
e.Logger.Fatal(e.Start(":30000")) | |||
</syntaxhighlight> | |||
For details on how to declare and implement various HTTP operations, see: {{Internal|OpenAPI_Specification_Path#Examples|OpenAPI Specification Path Examples}} | |||
=TLS Support= | |||
=Programming Model= | |||
==Figuring Out Whether the Server Has Started== | |||
==Stopping the Server== | |||
{{External|https://echo.labstack.com/docs/cookbook/graceful-shutdown}} | |||
<syntaxhighlight lang='go'> | |||
package main | |||
import ( | |||
"context" | |||
"github.com/labstack/echo/v4" | |||
"net/http" | |||
) | |||
func stopServer(c echo.Context) error { | |||
err := c.Echo().Shutdown(context.Background()) | |||
if err != nil { | |||
if err != http.ErrServerClosed { | |||
c.Echo().Logger.Fatal("shutting down the server") | |||
} | |||
} | |||
return nil | |||
} | |||
func main() { | |||
e := echo.New() | |||
e.GET("/stopServer", stopServer) | |||
e.Logger.Fatal(e.Start(":1323")) | |||
} | |||
</syntaxhighlight> | |||
==Retrieving Data== | |||
{{External|https://echo.labstack.com/docs/request}} | |||
===Request Body=== | |||
<syntaxhighlight lang='go'> | |||
func (s *PetStoreServer) CreatePet(ctx echo.Context) error { | |||
var payload petstore.PetPayload | |||
err := json.NewDecoder(ctx.Request().Body).Decode(& payload) | |||
if err != nil { | |||
return err | |||
} | |||
... | |||
p := petstore.NewPet(petPayload) | |||
resp, err := json.Marshal(p) | |||
if err != nil { | |||
return err | |||
} | |||
_, err = ctx.Response().Write(resp) | |||
return err | |||
} | |||
</syntaxhighlight> | |||
==Returning an Error Status Code== | |||
<syntaxhighlight lang='go'> | |||
func (s *PetStoreServer) GetPet(ctx echo.Context, id openapi_types.UUID) error { | |||
... | |||
if pet == nil { | |||
return echo.NewHTTPError(http.StatusNotFound, "no such ID: "+id.String()) | |||
} | |||
... | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 20:12, 22 March 2024
External
Internal
Overview
Install Dependencies
From the root directory of your module, execute:
go get github.com/labstack/echo/v4@v4.11.4
Server
package main
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
func hello(c echo.Context) error {
return c.String(http.StatusOK, "hello!")
}
func main() {
s := echo.New()
// Middleware
s.Use(middleware.Logger())
s.Use(middleware.Recover())
// Routes
s.GET("/", hello)
// Start server
s.Logger.Fatal(s.Start(":30000"))
}
Registering Handlers Generated by oapi-codegen from an OpenAPI Specification
oapi-codegen
generates a ServerInterface
interface that exposes methods for each path/operation pair specified in the OpenAPI specification:
// ServerInterface represents all server handlers.
type ServerInterface interface {
// (GET /pets)
GetPets(ctx echo.Context, params GetPetsParams) error
// (POST /pets)
CreatePet(ctx echo.Context) error
...
}
Implement the ServerInterface
:
type PetStoreServer struct {
}
func NewPetStoreServer() *PetStoreServer {
return &PetStoreServer{}
}
func (s *PetStoreServer) GetPets(ctx echo.Context, params petstore.GetPetsParams) error {
...
}
func (s *PetStoreServer) CreatePet(ctx echo.Context) error {
...
}
...
Then instantiate an echo
server and register the handlers:
s := NewPetStoreServer()
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// Routes
petstore.RegisterHandlers(e, s)
// Start server
e.Logger.Fatal(e.Start(":30000"))
For details on how to declare and implement various HTTP operations, see:
TLS Support
Programming Model
Figuring Out Whether the Server Has Started
Stopping the Server
package main
import (
"context"
"github.com/labstack/echo/v4"
"net/http"
)
func stopServer(c echo.Context) error {
err := c.Echo().Shutdown(context.Background())
if err != nil {
if err != http.ErrServerClosed {
c.Echo().Logger.Fatal("shutting down the server")
}
}
return nil
}
func main() {
e := echo.New()
e.GET("/stopServer", stopServer)
e.Logger.Fatal(e.Start(":1323"))
}
Retrieving Data
Request Body
func (s *PetStoreServer) CreatePet(ctx echo.Context) error {
var payload petstore.PetPayload
err := json.NewDecoder(ctx.Request().Body).Decode(& payload)
if err != nil {
return err
}
...
p := petstore.NewPet(petPayload)
resp, err := json.Marshal(p)
if err != nil {
return err
}
_, err = ctx.Response().Write(resp)
return err
}
Returning an Error Status Code
func (s *PetStoreServer) GetPet(ctx echo.Context, id openapi_types.UUID) error {
...
if pet == nil {
return echo.NewHTTPError(http.StatusNotFound, "no such ID: "+id.String())
}
...
}