/go-kit-middlewarer

A utility for generating layers for the go-kit framework

Primary LanguageGoMIT LicenseMIT

go-kit-middlewarer#

go-kit-middlewarer is a utility project meant to be used to quickly generate various layers of the go-kit microservice framework.

This utility is meant to be used with the go generate.

Documentation

Usage

To utilize this utility, you first need to build or install it. The easiest way to accomplish this is to run the following command:

go get github.com/ayiga/go-kit-middlewarer && \
go install github.com/ayiga/go-kit-middlewarer

After that's complete, please ensure that go-middle-warer is in your system's PATH Environment Variable, as it will attempt to be called by go generate.

Next, a file and an interface is needed to generate the layers for. An example would be something like this StringService taken from go-kit's example String Service

package service

//go:generate go-kit-middlewarer -type=StringService

// StringService from go-kit/kit's example
type StringService interface {
	// Uppercase returns an uppercase version of the given string, or an error.
	Uppercase(str string) (upper string, err error)

	// Count returns the length of the given string
	Count(str string) (count int)
}

Then, within that directory, and from terminal just run the command go generate, and the layers will automatically be generated.

Explanation

What's happening is go-kit-middlewarer is looking for an interface with the name specified by the type flag. It uses this information to pre-generate Service Middlewares, and transport bindings automatically so you don't have to worry about the logistics of setting all of that up.

The generated code is attempted to be organized in the following manner:

.
+-- endpoint
|   +-- defs_gen.go
+-- logging
|   +-- middleware_gen.go
+-- transport
|   +-- http
|   |    +-- client_gen.go
|   |    +-- http-client-loadbalanced_gen.go
|   |    +-- http-client_gen.go
|   |    +-- http-server_gen.go
|   |    +-- make-endpoint_gen.go
|   |    +-- request-response_gen.go
+-- <service>.go

The generated code will have created transport request and response structures for all methods specified within the interface. It will name them based on the names given by the arguments and results specified in the interface. If no names have been specified, then it will attempt to make some up. However, it is highly suggested that you do name your arguments and results.

Please note that the code generated by this package has this package as a dependency. This is primarily due to some convenience functionality around supporting multiple encoding and decoding types.

By default, all HTTP requests generated by this package should be able to support JSON, XML, and Gob encoding. This is assuming that the parameters and results are encodable by JSON, XML, and Gob. If they do not support a specific encoding, you do not have to use that encoding. However, they should support at least one.

To support these various encodings please see the golang documentation for each:

There are currently no generated binary files, and no default implementation is provided for the given interface. However, with the pieces generated, getting up and running should be as simple as writing some minimal logic code:

package main

import (
	"net/http"
	"strings"

	trans "{{.BasePackage}}/transport/http"
)

type StringService struct{}
func (StringService) Uppercase(str string) (string, error) {
	return strings.ToUpper(str), nil
}

func (StringService) Count(str string) int {
	return len(str)
}


func main() {
	var svc StringService

	trans.ServersForEndpoints(svc)
	http.ListenAndServe(":12345", nil)
}

Current Layers Generated

The list of layers that are currently generated are

  • HTTP Transport
  • Endpoint Path's for HTTP
  • Service Middleware Logging

TODO

  • Generate layers for Instrumenting
  • Generate layers for other transport types
  • Adjust functions to auto-wrap any embeded interfaces.
  • Clean-up main.go. (Most of this was taken from the stringer example to help parse AST trees. However, it needs to be cleaned up and shrunk wherever possible.)