Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically generate the boilerplate #70

Closed
peterbourgon opened this issue Jun 30, 2015 · 10 comments
Closed

Automatically generate the boilerplate #70

peterbourgon opened this issue Jun 30, 2015 · 10 comments

Comments

@peterbourgon
Copy link
Member

peterbourgon commented Jun 30, 2015

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.

@peterbourgon peterbourgon changed the title Automatically generate request/response types, endpoints, and bindings Automatically generate boilerplate Jun 30, 2015
@peterbourgon peterbourgon changed the title Automatically generate boilerplate Automatically generate the boilerplate Jun 30, 2015
@dahernan
Copy link

I also have some WIP here similar to @sasha-s, I'll try to push it this weekend, we can maybe mix aproach

@qingpingzhang
Copy link

go automatically generate code can reference goagen of goa

@compasses
Copy link

compasses commented Jun 2, 2016

Have you considering add predefined or default response for new endpoint? It maybe help for mock service during develop new API.
@dahernan

@philwinder
Copy link

👍 I consider the verbosity the only flaw of gokit. It complicates the code and hides important implementation details. It also increases the learning curve.

@kofalt
Copy link

kofalt commented Mar 24, 2017

@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.

@peterbourgon
Copy link
Member Author

@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.

@peterbourgon
Copy link
Member Author

@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!

@adamryman
Copy link

Tune has also been working on something kind of like this. It is called truss.

https://github.com/TuneLab/truss

@kujtimiihoxha
Copy link

You can also check out my new generator https://github.com/kujtimiihoxha/kit 🎉

@cce
Copy link

cce commented Sep 4, 2018

for people landing on this ticket, you should also look at: https://github.com/go-kit/kit/tree/master/cmd/kitgen from #589

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants