entproto: fix service.List pageToken for custom fields (UUID/string)#600
entproto: fix service.List pageToken for custom fields (UUID/string)#600kdevo wants to merge 3 commits intoent:masterfrom
Conversation
The current List service template generates faulty code if a custom GoType field is used (currently only UUID and string supported). While not tested on a large set of inputs, using a call to the `field_to_ent` template hopefully leads to a more sane behaviour, as it is also used for Get() and Update() function calls.
|
Any help/hint how to fix this with least impact or context why it is send as Base64-encoded string over the line is appreciated! I quickly went through #162 and I'm guessing it's because it is needed to accept any datatype as pageToken. Edit: With the last commit, I parse the UUID, and then call Probably the cleanest solution is the alternative mentioned in the opening comment but it's way more involved and it seems more reasonable to first fix the bug (even if not beautifully). Let me know what you think! |
...when using a custom GoType. This should keep the backward-compatibility by first parsing the UUID represented as string (like before) and then calling `field_to_ent`.
Motivation
The current List service template generates faulty code if a custom GoType field is used (currently only UUID and string types are supported by this fix).
I haven't tested this on a large set of inputs and probably I'm lacking context why the pageToken has been implemented this way (also why it is Base64-encoded), but using a call to the
field_to_enttemplate hopefully leads to a more sane behavior, as it is also used forGet()andUpdate()templates.Example schema
Example 1: UUID type
Example 2: String type
Diff of rendered code
IDLTEonly accepts custom type (in this case pulid.PULID). Therefore the green lines are working code:if req.GetPageToken() != "" { bytes, err := base64.StdEncoding.DecodeString(req.PageToken) if err != nil { return nil, status.Errorf(codes.InvalidArgument, "page token is invalid") } - pageToken, err := uuid.ParseBytes(bytes) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "page token is invalid") - } + pageToken := pulid.PULID{} + if err := (&pageToken).Scan(bytes); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid argument: %s", err) + } listQuery = listQuery. Where(evcharger.IDLTE(pageToken)) }Alternatives
It would probably be cleaner to allow implementing
UnmarshalProto/MarshalProtofor custom types similar like we can implement a customUnmarshalGQL/MarshalGQL. The reasoning is that the Valuer/Scanner interface used by the database driver is not necessarily what we want to represent in the protobuf types.