Skip to content

Automatically generate the boilerplate #70

Closed
@peterbourgon

Description

@peterbourgon

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions