Automatically generate the boilerplate
peterbourgon opened this issue ยท 10 comments
Given a service interface definition
type FooService interface {
Bar(ctx context.Context, i int, s string) (string, error)
}
It should be possible to automatically generate a stub service implementation, request and response types, endpoint factories, an endpoints struct, and transport bindings.
type stubFooService struct{}
func (s stubFooService) Bar(ctx context.Context, i int, s string) (string, error) {
return "", errors.New("not implemented")
}
type BarRequest struct {
I int
S string
}
type BarResponse struct {
S string
Err error
}
type makeBarEndpoint(s FooService) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(BarRequest)
s, err := s.Bar(ctx, req.I, req.S)
return BarResponse{S: s, Err: err}, nil
}
}
type Endpoints struct {
Bar endpoint.Endpoint
}
// Each transport binding should be opt-in with a flag to kitgen.
// Here's a basic sketch of what HTTP may look like.
// n.b. comments should encourage users to edit the generated code.
func NewHTTPHandler(endpoints Endpoints) http.Handler {
m := http.NewServeMux()
m.Handle("/bar", httptransport.NewServer(
endpoints.Bar,
DecodeBarRequest,
EncodeBarResponse,
)
return m
}
func DecodeBarRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req BarRequest
err := json.NewDecoder(r.Body).Decode(&req)
return req, err
}
func EncodeBarResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
return json.NewEncoder(w).Encode(response)
}
The CLI should have a UX like
$ kitgen -h
USAGE
kitgen path/to/service.go [flags]
FLAGS
-repo-layout default default, flat, ...
-allow-no-context false allow service methods to omit context parameter
The default repo layout should look like addsvc in the go-microservices repo; the flat repo layout should put all files and types in the same package. Other layout options could be considered.
I also have some WIP here similar to @sasha-s, I'll try to push it this weekend, we can maybe mix aproach
go automatically generate code can reference goagen of goa
Have you considering add predefined or default response for new endpoint? It maybe help for mock service during develop new API.
@dahernan
๐ I consider the verbosity the only flaw of gokit. It complicates the code and hides important implementation details. It also increases the learning curve.
@peterbourgon in #75 you mention that you'd welcome a fresh try at accomplishing this. Do you have thoughts on how that attempt went wrong, and how it could be tried again? I was looking to try out go-kit, and this exact issue is what's making me hesitate. If the generation is straightforward enough, maybe it's the sort of thing that myself or another interested beginner could attempt.
@kofalt I would absolutely welcome fresh eyes on this. In truth I think it would not be too hard: it would be a great project for someone who wants to get nice and cozy with package go/ast. I've updated the initial issue with some changes, please take a look! If you want to get serious, I'd love to chat more; you can find me on the Gophers Slack in #go-kit
.
@kujtimiihoxha has created https://github.com/kujtimiihoxha/gk which seems to be a fairly good approximation of my "spec" above. I haven't had a chance to play with it in earnest yet but I shall!
Tune has also been working on something kind of like this. It is called truss
.
You can also check out my new generator https://github.com/kujtimiihoxha/kit ๐
for people landing on this ticket, you should also look at: https://github.com/go-kit/kit/tree/master/cmd/kitgen from #589