-
Notifications
You must be signed in to change notification settings - Fork 32
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
HTTP API helpers #112
HTTP API helpers #112
Conversation
|
||
fix-path: | ||
mv -f $(PROTO_OUT)/temporal/api/* $(PROTO_OUT) && rm -rf $(PROTO_OUT)/temporal | ||
# Also copy the payload JSON helper | ||
cp $(PROTO_OUT)/internal/temporalcommonv1/payload_json.go $(PROTO_OUT)/common/v1/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I have to add methods to the generated Payload
/Payloads
structs. I could have written it in that directory and did a bunch of changes to the delete-all-regen logic in the Makefile, but instead I just wrote the implementation outside the directory and I just copy it on code gen.
t.grpcServer.Stop() | ||
return nil, err | ||
} | ||
if err = workflowservice.RegisterWorkflowServiceHandlerServer(ctx, serveMux, t); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will push the generated gateway code when temporalio/api#301 is reviewed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this depends on open PRs, please make a stacked PR to make review easier (e.g. push all the dependencies to some arbitrary branch and then set that as the base here).
It's more than that. It depends on a submodule from another repo being updated and a Makefile rerun (or rather a GitHub workflow triggered manually probably). You cannot just merge the other and then this magically is ok to merge. The PRs are in different repos and are inherently different things to review. Not sure how these different-repo PRs can be made any easier to review. |
# Conflicts: # go.mod # go.sum
|
||
// These are dummy messages, never used | ||
|
||
type Payloads struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dumb question, why do we need these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I guess because the "real" types on exist in the destination folder your copying into
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. I struggled with "write code over there and make the special file excluded from the wipe-and-regen process", or "write over here and copy". I chose the latter. There are pros/cons to both approaches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm good with the approach taken to write over and copy. It's hard to verify all the marshalling code is 100% correct, but I don't see anything obviously wrong
|
||
// JSONPb is a Marshaler which marshals/unmarshals into/from JSON | ||
// with the "github.com/golang/protobuf/jsonpb". | ||
// It supports fully functionality of protobuf unlike JSONBuiltin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean?
// It supports fully functionality of protobuf unlike JSONBuiltin. | |
// It supports fully functionality of protobuf unlike built in JSON. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the top of this file:
// This file taken from
// https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/runtime/marshal_jsonpb.go
// and altered to support Temporal JSONPB implementation. Specifically, the
// JSONPb struct was altered to accept an unmarshaler also and to change the
// marshaler to Temporal's.
This comment is in the source this came from. I would write code way better :-)
// the outer unmarshaler allows them. | ||
if gogojsonpb.Unmarshal(bytes.NewReader(b), p) == nil && len(p.Metadata) > 0 { | ||
// A raw payload must either have data or a binary/null encoding | ||
if len(p.Data) > 0 || string(p.Metadata["encoding"]) == "binary/null" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not an apologet of "every hardcoded string must be a const" but if you reference same string more than once, I would like to see them on top of this file in the const
block (I am talking about "encoding"
and "binary/null"
). Similar to DisablePayloadShorthandMetadataKey
but these will be really public (exported). Similar consts in Go SDK could just alias them.
On other hand, this is useful when one wants to keep ability to change them later (and change in one place only), and these consts are very well hardcoded (and immutable) not only in this repo but across many repos in entire org.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you reference same string more than once, I would like to see them on top of this file in the const block
In this case, these are basically company-wide constants have have no real home. I can move them to private constants in this file, but it makes little sense to me as they are used by two private methods colocated together.
Similar to DisablePayloadShorthandMetadataKey but these will be really public (exported).
But that is exported for a reason (it is needed by the server repo), there is no reason to export the other ones (user already has them from a better place). I only use these literals in two adjacent private methods and never would a user use them (they're in the Go SDK). I don't think we need to export more consts out of this mostly-generated package.
Similar consts in Go SDK could just alias them.
Aliasing was maybe not the best decision. But assuming you mean just have the Go SDK reference a new set of consts here, what benefit is there? If it's just to satisfy the idea that they're shared string literals (even though there would not be two public API places for them), I don't think that has enough benefits practically.
these consts are very well hardcoded (and immutable) not only in this repo but across many repos in entire org.
Exactly. They might as well be part of our proto definitions, but since they aren't we have string literals in the projects that reference them. It is unfortunate that api-go even exists (the SDK and server should be able to own their own proto generation) and luckily other languages aren't burdened with that. If it was reasonable I would not put this logic here but instead on the server where I need this, but since this is our "shared Go place for payloads", we need the specialized JSON conversion here I think.
// | ||
// The NewDecoder method returns a DecoderWrapper, so the underlying | ||
// *json.Decoder methods can be used. | ||
type JSONPb struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if it is JSON
(all caps) then it should be PB
not Pb
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not my code. See comment near top of file.
# Conflicts: # cmd/proxygenerator/go.mod # cmd/proxygenerator/go.sum # go.mod # go.sum # sdk/v1/task_complete_metadata.pb.go
What changed?
Implements helpers for HTTP API as proposed at temporalio/proposals#79, primarily around payload formatting. Specifically:
go.temporal.io/api/internal/temporaljsonpb
packageJSONPBMaybeMarshaler
andJSONPBMaybeUnmarshaler
interfaces which protos can implement for custom, optional JSON supportgo.temporal.io/api/internal/temporalgateway
packageJSONPBMaybeMarshaler
/JSONPBMaybeUnmarshaler
supportgo.temporal.io/api/internal/temporalcommonv1
packageJSONPBMaybeMarshaler
andJSONPBMaybeUnmarshaler
forPayloads
andPayload
to support shorthand JSON representationMakefile
updated to copy code written here togo.temporal.io/api/common/v1
where it lives alongside generated code (instead of trying to write code directly alongside generated code)go.temporal.io/api/proxy
JSONPBMarshaler
/NewJSONPBMarshaler
andJSONPBUnmarshaler
/NewJSONPBUnmarshaler
to create marshalers to support maybe-JSON interfaces (so for Payload shorthand)NewGRPCGatewayJSONPBMarshaler
to create a https://pkg.go.dev/github.com/grpc-ecosystem/grpc-gateway/runtime#Marshaler from the above marshaler/unmarshalerMakefile
to support building with gRPC gateway + Google HTTP annotationsThis is ready for review. This will not have the generated code updates until the API PR is merged. Related PRs: