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

add support for the google.api.HttpBody proto as a response #458

Closed

Conversation

theRealWardo
Copy link
Contributor

#457 fix proof of concept - probably needs some discussion on the bug as this is not very straight forward. I just hacked this together, no tests yet, so not ready for serious review until I hear from someone on the bug (if the general idea here is cool then I'll polish this PR up for submission).

@tmc
Copy link
Collaborator

tmc commented Sep 14, 2017

Thanks for your contribution! master has a build system fix, can you please rebase this?

@theRealWardo
Copy link
Contributor Author

@tmc sorry for the delay! rebased and pushed finally.

@tmc
Copy link
Collaborator

tmc commented Dec 6, 2017

@theRealWardo sorry, can you do so again?

@@ -7,7 +7,7 @@ import (
"net/textproto"

"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime/internal"
"github.com/therealwardo/grpc-gateway/runtime/internal"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should merge with this sourcing from another repo.

@achew22
Copy link
Collaborator

achew22 commented Dec 6, 2017

@tmc, I found out something nifty about github the other day. You can git clone git@github.com:theRealWardo/grpc-gateway, check out the branch that has a PR coming your way and then push back onto it. The default PR behavior is to grant the PR recipient write into that branch (which is you). We don't need to impotently wait for a PR author to rebase so we can confirm everything works before merging... yay! 🎆

@tmc
Copy link
Collaborator

tmc commented Jan 2, 2018

I'd expect this to come with greater test code change/addition.

@jinleileiking
Copy link

waiting for merge.

@jinleileiking
Copy link

Needs example to show me how to use it...

}

var wroteHeader bool
ctSet := false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm all for short variable names, but this is too far away from the code using it to use a 2 letter abbreviation IMO. "contentTypeSet" would be preferred

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@@ -0,0 +1,74 @@
package runtime
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think you could add a test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea sure, but let's finish the other discussion first so I don't have to change things too much.

@@ -15,8 +15,8 @@ type Marshaler interface {
NewDecoder(r io.Reader) Decoder
// NewEncoder returns an Encoder which writes bytes sequence into "w".
NewEncoder(w io.Writer) Encoder
// ContentType returns the Content-Type which this marshaler is responsible for.
ContentType() string
// ContentType returns the response Content-Type for "v".
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on what "v" would be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v is the same thing that Marshal(v interface{}) is passed, I'm honestly just following convention here. should I update comments on Marshal as well? (happy to do that just lmk)

side note, I am not actually sure why all of these interfaces are not instead of type proto.Message which is what is actually being passed...

// ContentType returns the Content-Type which this marshaler is responsible for.
ContentType() string
// ContentType returns the response Content-Type for "v".
ContentType(v interface{}) string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be a painful breaking change to the API. Is there ANY way to do this without passing in v?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm well the problem is that the content type right now is not dynamic. I suppose we could add another function like ContentTypeForMessage(m proto.Message) string and make that work as a preferred content-type setter. i.e. if ContentTypeForMessage(m proto.Message) string returns a non-empty string, we use it. otherwise we use the existing ContentType() string. now this has a similar problem as it changes a public interface, which would result in compilation errors for implementors anyway, so I'm afraid I don't have a clever solution. this feels like the lesser of two evils to me?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bumping this - any thoughts here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately adding another method to the interface suffers from the same API breaking change problem so I would rather go with the simpler breaking change if it is possible. Just spitballing cause I don't think it's possible, there isn't a way to make a type union or something, is there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually wow yea I think it is possible. so via a type union I think we can do something like this - https://play.golang.org/p/G4x7sEtEHbh - which in this case would mean we have something like this probably in this file:

// ContentType returns the Content-Type header value given a Marshaler or TypeAwareMarshaler and the interface to marshal v.
func contentType(m, v interface{}) string {
  switch t := m.(type) {
  case TypeAwareMarshaler:
    return t.ContentTypeForInterface(v)
  case Marshaler:
    return t.ContentType()
  }
  return ""
}

then we'd update all the marshaler.ContentType() calls in this package to contentType(marshaler, v). what do you think of that? I think that is not technically API breaking, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been staring at this and I think you're right. That would not be API breaking. I think we should go that route.

@@ -13,7 +13,7 @@ var (
acceptHeader = http.CanonicalHeaderKey("Accept")
contentTypeHeader = http.CanonicalHeaderKey("Content-Type")

defaultMarshaler = &JSONPb{OrigName: true}
defaultMarshaler = &HTTPBodyMarshaler{}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems incorrect. Why does the default marshaller need to change from this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why shouldn't the default behavior be to treat HTTP body protos specially?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a breaking change. I try not to make those except on major version bumps. If you want to be added to the list of 2.0 breaking changes and do it then, I'd be happy to do that.

@jinleileiking
Copy link

@theRealWardo Can I modify your codes? If you donot have time, I will make code changes. I like this to be merged.

@johanbrandhorst
Copy link
Collaborator

This looks like it still needs some work, and may even be considered for v2 if the submitter wants to change the default marshaller.

@johanbrandhorst
Copy link
Collaborator

Please rebase on master for new CI functionality.

@wimspaargaren
Copy link
Contributor

Hi all, Can someone tell me if there's still any work being done to support HttpBody proto as response?

@johanbrandhorst
Copy link
Collaborator

This PR looks abandoned. Would you like to pick up the mantle @wimspaargaren?

@wimspaargaren
Copy link
Contributor

Sure, I know it needs a rebase, but could you enhance a bit if there need to be more adjustments before this can be merged?

@johanbrandhorst
Copy link
Collaborator

Judging by the comments from @achew22 there still needs to be a decision made whether this should be a backwards compatible change (perhaps under a flag) and so mergable today or whether we want to make it a breaking change in which case it would have to wait until v2. As v2 is currently somewhat unclear, I would suggest the former. In any case, you personally couldn't take over this PR, you'd have to submit a new one because of how the CLA works.

@wimspaargaren
Copy link
Contributor

Allright! Flag or env var would work fine for me. I'll propose my own PR on Monday then.

@johanbrandhorst
Copy link
Collaborator

Superceded by #904

@theRealWardo
Copy link
Contributor Author

awesome! thanks for picking this up @wimspaargaren

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

Successfully merging this pull request may close these issues.

7 participants