Home

Awesome

Microgen

Tool to generate microservices, based on go-kit, by specified service interface.
The goal is to generate code for service which not fun to write but it should be written.

Install

go get -u github.com/devimteam/microgen/cmd/microgen

Note: If you have problems with building microgen, please, install dep and use dep ensure command to install correct versions of dependencies (#29).

Usage

microgen [OPTIONS]

microgen tool search in file first type * interface with docs, that contains // @microgen.

generation parameters provides through "tags" in interface docs after general // @microgen tag (space before @ required).

Recommended project layout

Microgen uses standard-like layout for generating boilerplate. Default layout of project:

├── cmd
│   └── user_service
│       └── main.go
├── pb
│   └── api.proto
├── service
│   ├── caching.go
│   ├── caching.microgen.go
│   ├── error_logging.microgen.go
│   ├── logging.microgen.go
│   ├── middleware.microgen.go
│   └── recovering.microgen.go
├── transport                  // And may be some others in future, NATS or AMQP for example
│   ├── grpc
│   │   ├── client.microgen.go
│   │   ├── protobuf_endpoint_converters.microgen.go
│   │   ├── protobuf_type_converters.microgen.go
│   │   └── server.microgen.go
│   ├── http
│   │   ├── client.microgen.go
│   │   ├── converters.microgen.go
│   │   └── server.microgen.go
│   ├── client.microgen.go
│   ├── endpoints.microgen.go
│   ├── exchanges.microgen.go
│   └── server.microgen.go
├── usersvc
│   ├── api.go
│   └── user.go
├── vendor/
├── Dockerfile
├── Gopkg.lock
├── Gopkg.toml
├── Makefile
└── README.md
root directory

Contains other dirs and top-level project files, like Dockerfile, Makefile, Readme.md, etc.

cmd

Contains applications.

transport

Contains all transport specific code for all transports: http, grpc, amqp, udp, and so on.

service

Middleware in past. Should contain service realisations and closures (middlewares).<br/> If you need new implementation of service, just add directory /v2/ or something else.

<project name>

Contains domain-specific types.

and others

Contains everything you want, just separate them by purposes.

Q: How microgen generates for this layout?<br/> A: cd <project name>; microgen -out=./..<br/>

To find more, check examples folder.

Options

NameDefaultDescription
-fileservice.goRelative path to source file with service interface
-out.Relative or absolute path to directory, where you want to see generated files
-v1Sets microgen verbose level. 0 - print only errors.
-helpfalsePrint usage information
-debugfalsePrint all microgen messages. Equivalent to -v=100.
-.protoPackage field in protobuf file. If not empty, service.proto file will be generated.

* Required option

Markers

Markers is a general tags, that participate in generation process. Typical syntax is: // @<tag-name>:

@microgen

Main tag for microgen tool. Microgen scan file for the first interface which docs contains this tag.
To add templates for generation, add their tags, separated by comma after @microgen: Example:

// @microgen middleware, logging
type StringService interface {
    ServiceMethod(ctx context.Context) (err error)
}

@protobuf

Protobuf tag is used for package declaration of compiled with protoc grpc package.
Example:

// @microgen grpc-server
// @protobuf github.com/user/repo/path/to/protobuf
type StringService interface {
    ServiceMethod(ctx context.Context) (err error)
}

@protobuf tag is optional, but required for grpc, grpc-server, grpc-client generation.

@grpc-addr

This tag allows to add construction for default grpc server addr in generated grpc client.

if addr == "" {
    addr = "service.string.StringService"
}

Example:

// @microgen grpc-client
// @grpc-addr service.string.StringService
type StringService interface {
    ServiceMethod(ctx context.Context) (err error)
}

Method's tags

@microgen -

Microgen will ignore method with this tag everywere it can.

// @microgen main, logging
type StringService interface {
    // @microgen -
    Count(ctx context.Context, text string, symbol string) (count int, positions []int, err error)
}

@logs-ignore

This tag is used for logging middleware, when some arguments or results should not be logged, e.g. passwords or files.
If context.Context is first argument, it ignored by default. Provide parameters names, separated by comma, to exclude them from logs.
Example:

// @microgen logging
type FileService interface {
    // @logs-ignore data
    UploadFile(ctx context.Context, name string, data []byte) (link string, err error)
}

@logs-len

This tag is used for logging middleware. It prints length of parameters. Example:

// @microgen logging
type FileService interface {
    // @logs-ignore data
    // @logs-len data
    UploadFile(ctx context.Context, name string, data []byte) (link string, err error)
}

@http-method

This tag is used for http server and client to set different from POST method. This tag has special validation rules for GET method. Example:

// @microgen logging
type StringService interface {
    // @http-method GET
    Count(ctx context.Context, text string, symbol string) (count int, positions []int, err error)
}

cache-key

This tag is used for caching middleware and allows user to write expression that should be used as key for cache instance.<br/> Key may be any string: it will directly writes to generated code.

// @microgen caching
type StringService interface {
    // @cache-key strings.ToLower(text)
    Count(ctx context.Context, text string, symbol string) (count int, positions []int, err error)
}

Tags

All allowed tags for customize generation provided here.

TagDescription
middlewareGeneral application middleware interface. Generates every time.
loggingMiddleware that writes to logger all request/response information with handled time. Generates every time.
error-loggingMiddleware that writes to logger errors of method calls, if error is not nil.
recoveringMiddleware that recovers panics and writes errors to logger. Generates every time.
cachingMiddleware that caches responses of service. Adds missed functions.
grpc-clientGenerates client for grpc transport with request/response encoders/decoders. Do not generates again if file exist.
grpc-serverGenerates server for grpc transport with request/response encoders/decoders. Do not generates again if file exist.
grpcGenerates client and server for grpc transport with request/response encoders/decoders. Do not generates again if file exist.
http-clientGenerates client for http transport with request/response encoders/decoders. Do not generates again if file exist.
http-serverGenerates server for http transport with request/response encoders/decoders. Do not generates again if file exist.
httpGenerates client and server for http transport with request/response encoders/decoders. Do not generates again if file exist.
mainGenerates basic package main for starting service. Uses other tags for minimal user changes.
tracingGenerates options and params for opentracing.
metricsGenerates transport endpoints middlewares for common tracing purposes.

Example

You may find examples in examples directory, where svc contains all, what you need for successful generation, and generated contains what you will get after microgen.

Follow this short guide to try microgen tool.

  1. Create file service.go inside GOPATH and add code below.
package stringsvc

import (
	"context"

	"github.com/devimteam/microgen/example/svc/entity"
)

// @microgen middleware, logging, grpc, http, recovering, main
// @protobuf github.com/devimteam/microgen/example/protobuf
type StringService interface {
	// @logs-ignore ans, err
	Uppercase(ctx context.Context, stringsMap map[string]string) (ans string, err error)
	Count(ctx context.Context, text string, symbol string) (count int, positions []int, err error)
	// @logs-len comments
	TestCase(ctx context.Context, comments []*entity.Comment) (tree map[string]int, err error)
}
  1. Open command line next to your service.go.
  2. Enter microgen. *
  3. You should see something like that:
@microgen 0.5.0
all files successfully generated
  1. Now, add and generate protobuf file (if you use grpc transport) and write transport converters (from protobuf/json to golang and vise versa).
  2. Use endpoints in your package main or wherever you want. (tag main generates some code for package main)

* GOPATH/bin should be in your PATH.

Interface declaration rules

For correct generation, please, follow rules below.

General:


GRPC and Protobuf:


HTTP GET method (// @http-method GET)

Dependency

list out of date! After generation your service may depend on this packages:

    "net/http"      // for http purposes
    "bytes"
    "encoding/json" // for http purposes
    "io/ioutil"
    "strings"
    "net"           // for http and grpc listners
    "net/url"       // for http purposes
    "fmt"
    "context"
    "time"          // for logging
    "os"            // for signal handling and os.Stdout
    "os/signal"     // for signal handling 
    "syscall"       // for signal handling
    "errors"        // for error handling
    

    "google.golang.org/grpc"                    // for grpc purposes
    "golang.org/x/net/context"
    "github.com/go-kit/kit"                     // for grpc purposes
    "github.com/golang/protobuf/ptypes/empty"   // for grpc purposes