examples/

directory
v0.1.0-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 9, 2020 License: Apache-2.0

README

Table of Contents

About

This directory contains example usages for Repose. The subdirectories contain source code that was generated by the tool, and also the configurations that were used for them.

CLI Usage Example

This short walkthrough shows the general usage of Repose by generating code from the Open API 3 Pet Store specification.

Configuration

Code generation usually begins with creating one or more config files. Repose has default values for everything, but we usually want to influence what the generated code will look like.

Repose uses the YAML format, you can generate an example file with the CLI tool:

repose get config --all --no-comments -o repose.yaml

This will create a repose.yaml file with all the configuration options.

Generating the server

Definitions

Each generator supports multiple targets (generated content) for generation, for Go types we need the types target from the go-general generator, and for this example we use the we use the server target from the go-echo generator that will generate an interface to use with Echo.

To generate the said targets, run:

repose generate -c repose.yaml \
    -t go-general:types,go-echo:server \
    -o echo-petstore/src/api/ \
    echo-petstore/spec/petstore-expanded.yaml

We used the -t flag to override the targets in the config file, but more complex usage would involve more configuration files instead.

The server interface that has to be implemented along with the types will be in the echo-petstore/src/api/ directory.

Scaffold

The go-echo generator supports generating a scaffold for the interface. It also uses the same generated types and server interface.

By default it is assumed that everything will be in the same package, but we would like to separate the scaffold from the definitions. In order to do that we must specify the path to the package where the definitions are, we can do that in the repose.yaml config as the go-echo generator has an option for it:

go-echo:
  options:
    serverPackagePath: "github.com/tamasfe/repose/examples/echo-petstore/src/api"

Finally we can generate the code:

repose gen -c repose.yaml \
    -t go-echo:scaffold \
    -o echo-petstore/src/server/ \
    echo-petstore/spec/petstore-expanded.yaml

To try it out create a main.go in the echo-petstore/src:

package main

import (
	"github.com/labstack/echo/v4"
	"github.com/tamasfe/repose/examples/echo-petstore/src/api"
	"github.com/tamasfe/repose/examples/echo-petstore/src/server"
)

func main() {
	e := echo.New()
	e.Server.Addr = ":8080"

	api.RegisterEchoServer(e, &server.ServerImpl{})

	panic(e.Server.ListenAndServe())
}

It will obviously panic for every handler, as nothing is implemented yet. It will also fail to start, because the server implementation has a Middleware method that provides middleware for the routes, but this is also yet to be implemented.

To implement the server, simply replace the panicking code.

First change the Middleware method so that at least the server can start:

// Middleware allows attaching middleware to each operation.
func (s *ServerImpl) Middleware() *api.ServerMiddleware {
	// repose:keep middleware_body
	return nil
	// repose:endkeep
}

Notice the repose:keep * and repose:endkeep comments, these are hints for the code generator on which code to keep. Do not delete these, as you might end up with some of your code getting lost. Note that the tags might change as well, in all cases Repose will prompt for confirmation before overwriting code. However it is always advised to have backups and code version control as bugs can always happen.

Let's also return a very good dog named Bonnie in the FindPetById handler:

func (s *ServerImpl) FindPetById(c echo.Context, id int64) (api.FindPetByIdHandlerResponse, error) {
	// repose:keep FindPetById_body
	return &api.Pet{
		NewPet: api.NewPet{
			Name: "Bonnie",
		},
		PetFragment1: api.PetFragment1{
			ID: id,
		},
	}, nil
	// repose:endkeep
}

Now if we run the server, and visit it in the browser, we should see Bonnie in the response with the ID we used in the URL.

Generating the client

We can use also generate a client for the API. The client target in the go-stdlib generator can create Go HTTP Requests that we can inspect and use to interact with the server.

We also need to update the config like we did for the scaffold:

go-stdlib:
  options:
    serverPackagePath: "github.com/tamasfe/repose/examples/echo-petstore/src/api"

And generate the code:

repose gen -c repose.yaml \
    -t go-stdlib:client \
    -o echo-petstore/src/client/ \
    echo-petstore/spec/petstore-expanded.yaml

And then use it:


// Create a Go HTTP client
httpClient := &http.Client{
  Timeout: time.Second * 30,
}

// Operations are namespaced by their paths
petsRequest, err := client.PetsWithIDClient("http://localhost:8080").FindPetById(1)
if err != nil {
  panic(err)
}

// Use the generated request
res, err := httpClient.Do(petsRequest)
if err != nil {
  panic(err)
}

// Finally read and print the body
b, err := ioutil.ReadAll(res.Body)
if err != nil {
  panic(err)
}
defer res.Body.Close()

fmt.Println(string(b))

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL