Why does my Go code not run? - go

package main
import (
"fmt"
"github.com/ant0ine/go-json-rest"
"net/http"
)
type App struct {
Id string
Name string
}
func GetApp(w *rest.ResponseWriter, req *rest.Request) {
user := App{
Id: req.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&user)
}
type MyResourceHandler struct {
rest.ResourceHandler
}
type ResourceController interface {
Show(w *rest.ResponseWriter, req *rest.Request)
Create(w *rest.ResponseWriter, req *rest.Request)
Update(w *rest.ResponseWriter, req *rest.Request)
Delete(w *rest.ResponseWriter, req *rest.Request)
}
func (self *MyResourceHandler) AddResource(name string, c ResourceController) error {
show_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Show(w, r)
}
create_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Create(w, r)
}
update_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Update(w, r)
}
delete_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Delete(w, r)
}
err := self.ResourceHandler.SetRoutes(
rest.Route{"GET", fmt.Sprintf("/%s/:id", name), show_func},
rest.Route{"POST", fmt.Sprintf("/%s", name), create_func},
rest.Route{"PUT", fmt.Sprintf("/%s/:id", name), update_func},
rest.Route{"DELETE", fmt.Sprintf("/%s/:id", name), delete_func},
)
return err
}
type AppController struct{}
func (self *AppController) Show(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}
func (self *AppController) Create(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}
func (self *AppController) Update(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}
func (self *AppController) Delete(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}
func main() {
handler := MyResourceHandler{}
controler := AppController{}
handler.AddResource("app", controler)
http.ListenAndServe(":9008", &handler)
}
I have implemented all of four methods of interface ResourceController, but it tells me:
./fakeapi.go:93: cannot use controler (type AppController) as type ResourceController in function argument:
AppController does not implement ResourceController (Create method requires pointer receiver)

It's in the error message: (Create method requires pointer receiver)
You've defined Create on *AppController (pointer to an AppController), but you're trying to use an AppController, which does not satisfy the interface.
The solution you probably want is to change controler := AppController{} to controler := &AppController{}

As cthom06 says, the answer is in the error.
The reason for the error message is that you have only implemented ResourceController when you are passing a pointer and not a value.
When you implemented Show, Create, etc., you used
func (self *AppController)...
This requires the method to get a pointer receiver, but AddResources is given the value of controler, not the pointer.
Here is some example code to show the problem:
package main
import "fmt"
type I interface {
Show(i int)
}
type T struct{}
func (t *T) Show(i int) {
fmt.Println(i)
}
func CallShow(i I) {
i.Show(32);
}
func main() {
obj := T{}
// CallShow(obj) // This doesn't work unless you change func (t *T) to func (t T)
CallShow(&obj) // This works because you pass a pointer
}

Also "ResourceHandler" is deprecated. I would recommend to use the v3 API:
api := rest.NewApi()
api.Use(rest.DefaultDevStack...)
router, err := rest.MakeRouter(
// your routes here ...
)
if err != nil {
log.Fatal(err)
}
api.SetApp(router)
log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))
Antoine - go-json-rest author

Related

Simplifying route handler to handle parameters without framework

In rocket.rs, we've this simple route code:
#[get("/hello/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
where if you were to visit http://localhost:8000/hello/John/58 in the browser, you’d see:
Hello, 58 year old named John!
I read this, but the accepted answer is about a way to do Go url parameters mapping for single route, that could read http://localhost:8080/blob/123/test as /blob/{id}/test and display the required route.
I know there are some great routers/frameworks there, but looking to build simple code myself to understand http route handlers in a better way.
Let's say I've:
type Tender struct {
tenderReference string
venderCode int
}
func (t Tender) readWrite() {
fmt.Printf("Tender %s is ready for vendor %d to review and submit\n", t.tenderReference, t.venderCode)
}
func (t Tender) readOnly(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Tender %s already submitted by vender %d\n", t.tenderReference, t.venderCode)
}
And want my routes to be something like:
/api/tender/readWrite/{tenderReference}/vendor/{venderCode} that is calling func (t Tender) readWrite(){}
/api/tender/readOnly/{tenderReference}/vendor/{venderCode} that is calling func (t Tender) readOnly(){}
How many route handler do I have to build?
I solved it as below, other thoughts are welcomed:
404.go
package main
import (
"fmt"
"net/http"
)
func handle404(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "mmm, it looks you are playing around, page is not available :)\n")
}
getField.go
package main
import "net/http"
type ctxKey struct{}
func getField(r *http.Request, index int) string {
fields := r.Context().Value(ctxKey{}).([]string)
return fields[index]
}
routes.go
package main
import (
"net/http"
"regexp"
)
type route struct {
method string
regex *regexp.Regexp
handler http.HandlerFunc
}
var routes = []route{
newRoute("GET", "/api/tender/(rw|r)/([^/]+)/vendor/([0-9]+)", apiTenders),
}
func newRoute(method, pattern string, handler http.HandlerFunc) route {
return route{method, regexp.MustCompile("^" + pattern + "$"), handler}
}
tendor.go
package main
import (
"fmt"
"net/http"
"strconv"
)
type Tender struct {
tenderReference string
venderCode int
}
// Handles GET /api/tender/(rw|r)/([^/]+)/vendor/([0-9]+)
func apiTenders(w http.ResponseWriter, r *http.Request) {
action := getField(r, 0)
tenderReference := getField(r, 1)
venderCode, _ := strconv.Atoi(getField(r, 2))
tender := Tender{tenderReference, venderCode}
switch action {
case "rw":
tender.readWrite(w, r) // Display tender and allow vendor to submit feedback
case "r":
tender.readOnly(w, r) // Display readOnly copy of the tender
default:
fmt.Fprintf(w, "Tendert ERROR\n")
}
}
func (t Tender) readWrite(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Tender %s is ready for vendor %d to review and submit\n", t.tenderReference, t.venderCode)
}
func (t Tender) readOnly(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Tender %s already submitted by vender %d\n", t.tenderReference, t.venderCode)
}
server.go
package main
import (
"context"
"fmt"
"net/http"
"strings"
)
type apiHandler struct{}
func main() {
http.Handle("/api/", apiHandler{})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// The "/" pattern matches everything, so we need to check
// that we're at the root here.
if req.URL.Path != "/" {
http.NotFound(w, req)
return
}
fmt.Fprintf(w, "Welcome to the home page!")
})
http.ListenAndServe(":8000", nil)
}
func (apiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var allow []string
for _, route := range routes {
matches := route.regex.FindStringSubmatch(r.URL.Path)
if len(matches) > 0 {
if r.Method != route.method {
allow = append(allow, route.method)
continue
}
ctx := context.WithValue(r.Context(), ctxKey{}, matches[1:])
route.handler(w, r.WithContext(ctx))
return
}
}
if len(allow) > 0 {
w.Header().Set("Allow", strings.Join(allow, ", "))
http.Error(w, "405 method not allowed", http.StatusMethodNotAllowed)
return
}
handle404(w, r)
//http.NotFound(w, r)
}

Find structure to which *ast.FuncDecl attached

Here is simple realisation of Handler interface:
type someApi struct {
mu *sync.RWMutex
}
func (api *someApi) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
func NewSomeApi(mu *sync.RWMutex) *someApi {
return &someApi{
mu: mu,
}
}
func (srv *someApi) Create() {
// some realisation
}
func Create() {
// some realisation
}
I want parse file with go/ast and create decorator for someApi.Create function.
It simple to get func name with *ast.FuncDecl.Name, but how can I find which of Create funcs attached to someApi?
Sloved this by iterating through *ast.FuncDecl.Recv.List:
for _, l := range fn.Recv.List { // fn is *ast.FuncDecl
star, ok := l.Type.(*ast.StarExpr)
if !ok {
continue
}
fmt.Println(star.X) // someApi
}

How do I use Twitter API with github.com/ChimeraCoder/anaconda?

I have a web API written Go, I would like to use it to consume the Twitter API and return some properties from a user's timeline.
I have added https://github.com/ChimeraCoder/anaconda to my web API, however I cannot understand from the docs just how to get a timeline for a user.
This is my application currently.
I am trying to use the FeedHandler method. I can trigger a search, but when it comes to actually returning a user's timeline, I am stuck.
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"github.com/ChimeraCoder/anaconda"
"github.com/gorilla/mux"
)
type Meta struct {
Description string `json:"description"`
Version string `json:"version"`
Bugs GitHubLink `json:"bugs"`
}
type GitHubLink struct {
Url string `json:"url"`
}
type ErrorMessage struct {
Status int `json:"status"`
Message string `json:"message"`
}
var (
consumerKey = getenv("TWITTER_CONSUMER_KEY")
consumerSecret = getenv("TWITTER_CONSUMER_SECRET")
)
func getenv(name string) string {
v := os.Getenv(name)
if v == "" {
panic("required environment variable " + name + "is missing")
}
return v
}
func main() {
anaconda.SetConsumerKey(consumerKey)
anaconda.SetConsumerSecret(consumerSecret)
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/feed/{screenName}", FeedHandler)
r.HandleFunc("/healthz", HealthzHandler)
r.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
log.Fatal(http.ListenAndServe(":8000", r))
}
func HomeHandler(w http.ResponseWriter, r *http.Request) {
meta := Meta{
Description: "API returning twitter.com posted images",
Version: "0.0.0",
Bugs: GitHubLink{Url: "https://foo.bar"}}
json.NewEncoder(w).Encode(meta)
}
func FeedHandler(w http.ResponseWriter, r *http.Request) {
api := anaconda.NewTwitterApi("", "")
// vars := mux.Vars(r)
tweets := api.GetUserTimeline('<users_screen_name>')
// searchResult, _ := api.
// for _, tweet := range searchResult.Statuses {
// fmt.Println(tweet.Text)
// }
fmt.Fprintf(w, "Not Implemented Yet")
}
func HealthzHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-cache, no-store, max-age=0")
}
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
errorMessage := ErrorMessage{Status: 404, Message: "Request resource does not exist"}
json.NewEncoder(w).Encode(errorMessage)
}
You need to pass in the user's screen name as a property on url.Values{}
func FeedHandler(w http.ResponseWriter, r *http.Request) {
api := anaconda.NewTwitterApi("", "")
v := url.Values{}
v.Set("screen_name", "some_user_name")
searchResult, _ := api.GetUserTimeline(v)
json.NewEncoder(w).Encode(searchResult)
}

How to test an endpoint in go?

I wrote a small test function in go. I'm having hard time in making a request to actual endpoint and test it. I tried importing the file which has the handler function (I think I'm trying to import whole directory : import (".")). Both my project.go and handler_test.go are in the same directory (I don't think this matters). Could someone give me heads up so that I can write more tests.
Here is my project.go:
package main
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"github.com/rs/cors"
)
type Person struct {
ID string `json:"id,omitempty"`
Firstname string `json:"firstname,omitempty"`
Lastname string `json:"lastname,omitempty"`
Address *Address `json:"address,omitempty"`
}
type Address struct {
City string `json:"city,omitempty"`
State string `json:"state,omitempty"`
}
var people []Person;
func GetPersonEndpoint(w http.ResponseWriter, req *http.Request) {
params := mux.Vars(req)
for _, item := range people {
if item.ID == params["id"] {
json.NewEncoder(w).Encode(item)
return
}
}
json.NewEncoder(w).Encode(&Person{})
}
func GetPeopleEndpoint(w http.ResponseWriter, req *http.Request) {
json.NewEncoder(w).Encode(people)
}
func CreatePersonEndpoint(w http.ResponseWriter, req *http.Request) {
params := mux.Vars(req)
var person Person
_ = json.NewDecoder(req.Body).Decode(&person)
person.ID = params["id"]
people = append(people, person)
json.NewEncoder(w).Encode(people)
}
func DeletePersonEndpoint(w http.ResponseWriter, req *http.Request) {
params := mux.Vars(req)
for index, item := range people {
if item.ID == params["id"] {
people = append(people[:index], people[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(people)
}
func main() {
Router := mux.NewRouter()
people = append(people, Person{ID: "1", Firstname: "sarath", Lastname: "v", Address: &Address{City: "sunnyvale", State: "CA"}})
people = append(people, Person{ID: "2", Firstname: "dead", Lastname: "pool"})
// router.PathPrefix("/tmpfiles/").Handler(http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("."))))
Router.HandleFunc("/people", GetPeopleEndpoint).Methods("GET")
Router.HandleFunc("/people/{id}", GetPersonEndpoint).Methods("GET")
Router.HandleFunc("/people/{id}", CreatePersonEndpoint).Methods("POST")
c := cors.New(cors.Options{
AllowedOrigins: []string{"http://localhost:3000"},
AllowCredentials: true,
})
// Insert the middleware
handler := c.Handler(Router)
http.ListenAndServe(":12345", handler)
}
Here is my handler_test.go. In this code I'm testing GetPersonEndPoint.
package main
import (
"."
"net/http"
"net/http/httptest"
"testing"
"encoding/json"
)
func checkResponseCode(t *testing.T, expected, actual int) {
if expected != actual {
t.Errorf("Expected response code %d. Got %d\n", expected, actual)
}
}
func executeRequest(req *http.Request) *httptest.ResponseRecorder {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(GetPersonEndpoint)
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
fmt.Printf("Handler returned wrong status code: got %v want %v" , status, http.statusOk);
}
return rr
}
func TestGetPersonEndPoint(t *testing.T){
req, _ := http.NewRequest("GET", "/people/5", nil)
response := executeRequest(req)
checkResponseCode(t, http.StatusNotFound, response.Code)
var m map[string]string
json.Unmarshal(response.Body.Bytes(), &m)
if m["error"] != "Product not found" {
t.Errorf("Expected the 'error' key of the response to be set to 'Product not found'. Got '%s'", m["error"])
}
}
And finally this is the error:
./new.go:14: main redeclared in this block
previous declaration at ./myproject.go:62
./new.go:20: not enough arguments in call to server.ListenAndServeTLS
have ()
want (string, string)
Have a look at some http tests I've written: https://github.com/eamonnmcevoy/go_web_server/blob/master/pkg/server/user_router_test.go
// Arrange
us := mock.UserService{}
testUserRouter := NewUserRouter(&us, mux.NewRouter())
...
w := httptest.NewRecorder()
r, _ := http.NewRequest("PUT", "/", payload)
r.Header.Set("Content-Type", "application/json")
testUserRouter.ServeHTTP(w, r)
Simply create an instance of your router and call the endpoints using go's httptest. This snippet will perform a PUT request at the default endpoint /

How to fix this issue with grpc method handler

I'm new to golang and wanted to experiment with grpc code to get a better understanding of it. In order to do so I followed the example shown here:
https://devicharan.wordpress.com/
The source code is here:
https://github.com/devicharan/basicwebapp
Unfortunately, when I run this code and do a go build I get an error message with the following:
# basicwebapp/proto
proto/CatalogService.pb.go:126: cannot use _CatalogService_GetProductCatalog_Handler (type func(interface {}, context.Context, []byte) (proto.Message, error)) as type grpc.methodHandler in field value
proto/RecommendationService.pb.go:99: cannot use _RecommendationService_GetRecommendations_Handler (type func(interface {}, context.Context, []byte) (proto.Message, error)) as type grpc.methodHandler in field value
I don't know what this means or what I need to change in order to begin finding a fix. Is it a problem with the code itself or with my Go configuration? Also, is there a good debugger for Go that someone can recommend?
Here is the code for CatalogService.pb.go:
// Code generated by protoc-gen-go.
// source: CatalogService.proto
// DO NOT EDIT!
/*
Package protos is a generated protocol buffer package.
It is generated from these files:
CatalogService.proto
Product.proto
RecommendationService.proto
It has these top-level messages:
Category
CatalogResponse
CatalogRequest
*/
package protos
import proto "github.com/golang/protobuf/proto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
type Category struct {
CategoryName string `protobuf:"bytes,1,opt,name=categoryName" json:"categoryName,omitempty"`
}
func (m *Category) Reset() { *m = Category{} }
func (m *Category) String() string { return proto.CompactTextString(m) }
func (*Category) ProtoMessage() {}
type CatalogResponse struct {
Products []*Product `protobuf:"bytes,1,rep,name=products" json:"products,omitempty"`
}
func (m *CatalogResponse) Reset() { *m = CatalogResponse{} }
func (m *CatalogResponse) String() string { return proto.CompactTextString(m) }
func (*CatalogResponse) ProtoMessage() {}
func (m *CatalogResponse) GetProducts() []*Product {
if m != nil {
return m.Products
}
return nil
}
type CatalogRequest struct {
Category *Category `protobuf:"bytes,1,opt,name=category" json:"category,omitempty"`
}
func (m *CatalogRequest) Reset() { *m = CatalogRequest{} }
func (m *CatalogRequest) String() string { return proto.CompactTextString(m) }
func (*CatalogRequest) ProtoMessage() {}
func (m *CatalogRequest) GetCategory() *Category {
if m != nil {
return m.Category
}
return nil
}
func init() {
}
// Client API for CatalogService service
type CatalogServiceClient interface {
GetProductCatalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error)
}
type catalogServiceClient struct {
cc *grpc.ClientConn
}
func NewCatalogServiceClient(cc *grpc.ClientConn) CatalogServiceClient {
return &catalogServiceClient{cc}
}
func (c *catalogServiceClient) GetProductCatalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error) {
out := new(CatalogResponse)
err := grpc.Invoke(ctx, "/protos.CatalogService/GetProductCatalog", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for CatalogService service
type CatalogServiceServer interface {
GetProductCatalog(context.Context, *CatalogRequest) (*CatalogResponse, error)
}
func RegisterCatalogServiceServer(s *grpc.Server, srv CatalogServiceServer) {
s.RegisterService(&_CatalogService_serviceDesc, srv)
}
func _CatalogService_GetProductCatalog_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
in := new(CatalogRequest)
if err := proto.Unmarshal(buf, in); err != nil {
return nil, err
}
out, err := srv.(CatalogServiceServer).GetProductCatalog(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
var _CatalogService_serviceDesc = grpc.ServiceDesc{
ServiceName: "protos.CatalogService",
HandlerType: (*CatalogServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetProductCatalog",
Handler: _CatalogService_GetProductCatalog_Handler,
},
},
Streams: []grpc.StreamDesc{},
}
And this is RecommendationService.pg.go
// Code generated by protoc-gen-go.
// source: RecommendationService.proto
// DO NOT EDIT!
package protos
import proto "github.com/golang/protobuf/proto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
type RecommendationResponse struct {
Result []*RecommendationResponse_Recommendation `protobuf:"bytes,1,rep,name=result" json:"result,omitempty"`
}
func (m *RecommendationResponse) Reset() { *m = RecommendationResponse{} }
func (m *RecommendationResponse) String() string { return proto.CompactTextString(m) }
func (*RecommendationResponse) ProtoMessage() {}
func (m *RecommendationResponse) GetResult() []*RecommendationResponse_Recommendation {
if m != nil {
return m.Result
}
return nil
}
type RecommendationResponse_Recommendation struct {
Rating int32 `protobuf:"varint,1,opt,name=rating" json:"rating,omitempty"`
Productid int32 `protobuf:"varint,2,opt,name=productid" json:"productid,omitempty"`
}
func (m *RecommendationResponse_Recommendation) Reset() { *m = RecommendationResponse_Recommendation{} }
func (m *RecommendationResponse_Recommendation) String() string { return proto.CompactTextString(m) }
func (*RecommendationResponse_Recommendation) ProtoMessage() {}
func init() {
}
// Client API for RecommendationService service
type RecommendationServiceClient interface {
GetRecommendations(ctx context.Context, in *Product, opts ...grpc.CallOption) (*RecommendationResponse, error)
}
type recommendationServiceClient struct {
cc *grpc.ClientConn
}
func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {
return &recommendationServiceClient{cc}
}
func (c *recommendationServiceClient) GetRecommendations(ctx context.Context, in *Product, opts ...grpc.CallOption) (*RecommendationResponse, error) {
out := new(RecommendationResponse)
err := grpc.Invoke(ctx, "/protos.RecommendationService/GetRecommendations", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for RecommendationService service
type RecommendationServiceServer interface {
GetRecommendations(context.Context, *Product) (*RecommendationResponse, error)
}
func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {
s.RegisterService(&_RecommendationService_serviceDesc, srv)
}
func _RecommendationService_GetRecommendations_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
in := new(Product)
if err := proto.Unmarshal(buf, in); err != nil {
return nil, err
}
out, err := srv.(RecommendationServiceServer).GetRecommendations(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
var _RecommendationService_serviceDesc = grpc.ServiceDesc{
ServiceName: "protos.RecommendationService",
HandlerType: (*RecommendationServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetRecommendations",
Handler: _RecommendationService_GetRecommendations_Handler,
},
},
Streams: []grpc.StreamDesc{},
}
Basically your protoc-gen-go doesn't match the version of grpc. So sync them both to the latest version and reinstall protoc-gen-go will resolve the issue:
go get -u github.com/golang/protobuf/
cd github.com/golang/protobuf/
make
go get -u github.com/grpc/grpc-go
For anyone running into the same problem, what I did was simply change how I built the proto files. There is a comment on the blog page that highlights some missing steps, I followed it and did the following protoc command to generate code from the proto files:
protoc --go_out=plugins=grpc:. *.proto
I ran this command in the directory with my proto files and then did a go build on my main.go file, now everything is working fine.
I am having the same issue and reinstalling or the new command doesn't seem to work.
However: If you change
codec grpc.Codec, buf []byte
in the Handler Definition into:
dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor
and
codec.Unmarshal(buf, in)
into
dec(in)
(All in the Handler Definition in your .pb.go file)
it seems to work.
Changing this file is of course not optimal and every time you recompile it will override your changes, but at least there is a workaround until I figure out what I messed up.

Resources