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

[Question] Behavior of empty repeated field #2458

Closed
Bo0km4n opened this issue Nov 15, 2018 · 3 comments
Closed

[Question] Behavior of empty repeated field #2458

Bo0km4n opened this issue Nov 15, 2018 · 3 comments

Comments

@Bo0km4n
Copy link

Bo0km4n commented Nov 15, 2018

What version of gRPC are you using?

1.16.0

What version of Go are you using (go version)?

go version go1.11.1 darwin/amd64

What operating system (Linux, Windows, …) and version?

maxOS High Sierra 10.13.6

What did you do?

Hi, everyone.
I have a question about handling empty array of protobuf's repeated fields.

The following shows two codes of client and server and proto file.

server code

func launchServer() {
	fmt.Println("<<<<< server >>>>>")
	lis, err := net.Listen("tcp", ":5050")
	if err != nil {
		log.Fatal(err)
	}
	s := grpc.NewServer()
	RegisterShopAPIServer(s, newShopAPIHandler())

	reflection.Register(s)
	if err := s.Serve(lis); err != nil {
		log.Fatal(err)
	}
}

// implementation grpc shop api
type shopAPI struct{}

func newShopAPIHandler() *shopAPI {
	return &shopAPI{}
}

func (s *shopAPI) List(c context.Context, in *Empty) (*Books, error) {
	res := &Books{
		DebugStringFields: []string{},
		Books:             []*Book{
			//  {Price: 500, Name: "Hoge"},
		},
	}
	resJsonb, _ := json.Marshal(res)
	fmt.Println(string(resJsonb))
	return res, nil
}

client code

func launchClient() {
	conn, err := grpc.Dial("localhost:5050", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}

	defer conn.Close()
	cli := NewShopAPIClient(conn)
	res, err := cli.List(context.Background(), &Empty{})
	if err != nil {
		log.Fatal(err)
	}
	jsonb, _ := json.Marshal(res)
	fmt.Println(string(jsonb))
}

shop proto file

syntax = "proto3";

package main;

service ShopAPI {
    rpc List(Empty) returns(Books);
}

message Empty {}

message Books {
    repeated string debug_string_fields = 1;
    repeated Book books = 2;
}

message Book {
    string name = 1;
    int64 price = 2;
}

The result of client requesting server and the output of server side.

client

{"debug_string_fields":null,"books":null}

server

<<<<< server >>>>>
{"debug_string_fields":[],"books":[]}

What did you expect to see?

I expect client side response like this:

{"debug_string_fields":[],"books":[]}

I guessed that Books fields are not null, cause assigned empty array: Books: []*Book{},.

Currently check the field of response, if the length of the array is 0, you have to write code to allocate an empty array like this:

res, err := cli.List(context.Background(), &Empty{})
	if err != nil {
		log.Fatal(err)
	}
 if len(res.Books) == 0 {
  res.Books = []*Book{}
}

This seems not to be a very smart solution. Please let me know if there is any good way.

@menghanl
Copy link
Contributor

Which json library are you using?

The repeated fields are tagged with json:"...,omitempty", so it should be omitted in this case.

If this is still not helping, try the proto json package instead: https://godoc.org/github.com/golang/protobuf/jsonpb#Marshaler.Marshal

@Bo0km4n
Copy link
Author

Bo0km4n commented Nov 16, 2018

Thanks reply! I'm using standard json library.

Then, I removed tag which omitempty, but never changed result.
I'll try use jsonpb just now.

@Bo0km4n
Copy link
Author

Bo0km4n commented Nov 16, 2018

@menghanl I'm tried jsonpb. That's behavior is I'm expected!!! Thanks 👍 !

@dfawley dfawley closed this as completed Nov 16, 2018
@lock lock bot locked as resolved and limited conversation to collaborators May 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants