Labstack/echo: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(20 intermediate revisions by the same user not shown)
Line 13: Line 13:
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
go get github.com/labstack/echo/v4@v4.11.4
go get github.com/labstack/echo/v4@v4.11.4
</syntaxhighlight>
=Server=
<syntaxhighlight lang='go'>
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"))
}
</syntaxhighlight>
</syntaxhighlight>


=Registering Handlers Generated by oapi-codegen from an OpenAPI Specification=
=Registering Handlers Generated by oapi-codegen from an OpenAPI Specification=
{{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'>
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 {
  ...
}
...
</syntaxhighlight>
Then instantiate an <code>echo</code> server and register the handlers:
<syntaxhighlight lang='go'>
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"))
</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>

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 Server Code Generation

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:

OpenAPI Specification Path Examples

TLS Support

Programming Model

Figuring Out Whether the Server Has Started

Stopping the Server

https://echo.labstack.com/docs/cookbook/graceful-shutdown
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

https://echo.labstack.com/docs/request

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())
	}
    ...
}