Coder Social home page Coder Social logo

Comments (6)

jhump avatar jhump commented on June 22, 2024

@bwplotka, grpcurl does accept snake case in addition to camel case. Or, more precisely, if you give it a field name that does not match any of the message's field names in JSON format, it will assume you are using "original names" (e.g. the name of the field in the proto, which might be snake case) and check to see if the name matches that way.

Are you saying you were getting an error because the snake-case names were not being parsed? Perhaps you could provide some more info to demonstrate the problem, like a simple proto file and example invocation that do not behave as expected?

BTW, if you simply give a name that is not in the message, you will get an error message:

$ grpcurl -d '{"foo":"bar"}' api.grpc.me:443 listennotes.v1.Podcasts.GetEpisodes

Error invoking method "listennotes.v1.Podcasts.GetEpisodes": error getting request data: 
message type listennotes.v1.EpisodesRequest has no known field named foo

from grpcurl.

w3irdrobot avatar w3irdrobot commented on June 22, 2024

Where is this translation done? I can't seem to be able to get grpcurl to automatically transform my snake_case'd keys to the attributes in the protobuf message.

from grpcurl.

jhump avatar jhump commented on June 22, 2024

@searsaw, I don't really understand the question. Are you looking for where in the code this is done? I believe this is happening inside the JSON unmarshaling in github.com/jhump/protoreflect/dynamic.

Do you have a simple proto file and invocation of grpcurl that demonstrates the issue you are seeing? If I can repro the issue, I can probably provide more help getting it to work (or, if it's a bug, work on a patch).

from grpcurl.

w3irdrobot avatar w3irdrobot commented on June 22, 2024

user.proto

syntax = "proto3";
package main;

service Users {
  rpc Create(User) returns (User) {}
}

message User {
  string ID = 1;
  string FirstName = 2;
  string LastName = 3;
  string Email = 4;
}

main.go

package main

import (
	"context"
	"log"
	"net"

	"github.com/segmentio/ksuid"

	"google.golang.org/grpc"
)

func main() {
	lis, err := net.Listen("tcp", ":3001")
	if err != nil {
		log.Fatal("Error occurred getting tcp listener", err)
	}

	var options []grpc.ServerOption
	gServer := grpc.NewServer(options...)
	service := &Server{}
	RegisterUsersServer(gServer, service)

	log.Println("gRPC service started on :3001")
	log.Fatal(gServer.Serve(lis))
}

type Server struct{}

func (s *Server) Create(ctx context.Context, user *User) (*User, error) {
	user.ID = ksuid.New().String()
	return user, nil
}

deploy.sh

#!/bin/bash

grpcurl \
  -plaintext \
  -proto user.proto \
  -d '{"first_name": "George", "last_name": "Foreman", "email": "[email protected]"}' \
  localhost:3001 main.Users.Create

When build the proto file into Golang code, run the server, and run the deploy.sh script, i get the following message.

Error invoking method "main.Users.Create": error getting request data: message type main.User has no known field named first_name

from grpcurl.

jhump avatar jhump commented on June 22, 2024

@searsaw, I think there is some confusion around the JSON format for protobufs as well as the usual naming conventions for identifiers in your .proto source files.

When I said that snake case is supported, I meant that the actual proto name is supported. And the typical convention for field names in proto is that they are snake case:
https://developers.google.com/protocol-buffers/docs/style#message-and-field-names

In your example, the original name is not snake case -- it is upper-camel-case. So the correct field name to use is FirstName.

If you do use snake-case in your proto source (e.g. first_name), it will still generate Go code using upper-camel-case (e.g. the field in the generated struct is still FirstName). You can then use either the JSON name of the field or the original name (which is snake case). The JSON name of the field comes from its json_name option; or, for fields that have no such option, it is the camel-case version of the name (e.g. firstName).

Here is more info on the JSON format for protocol buffers. This is what grpcurl expects as input:
https://developers.google.com/protocol-buffers/docs/proto3#json

from grpcurl.

w3irdrobot avatar w3irdrobot commented on June 22, 2024

Thanks for this. Yeah it was just a misunderstanding with how I wrote my proto files. Once I started using the snake_case attribute names in my proto file, it all started working correctly. Thank you for the help!

from grpcurl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.