-
Notifications
You must be signed in to change notification settings - Fork 20
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
fieldmask: use field behavior for applying updates #134
Comments
Hello everyone, Just a friendly comment to revive this issue 👀 func (s *iamSvc) UpdateUser(ctx context.Context, in *iamv1.UpdateUserRequest) (*iamv1.User, error) {
// You must first validate and authorize the request but it is out of scope
now := timestamppb.Now()
user, err := s.usersRepo.GetUser(ctx, in.User.Name)
if err != nil {
return nil, err
}
if err := fieldmask.Update(in.UpdateMask, user, in.User); err != nil {
// An error is thrown when an IMMUTABLE constraint is violated
return nil, errors.Wrap(err, errors.CodeInvalidArgument, "invalid update mask")
}
// user.CreateTime is not updated because of the OUTPUT_ONLY constraint
user.UpdateTime = now
if err := s.usersRepo.SaveUser(ctx, user); err != nil {
return nil, err
}
return user, nil
} With very little changes you can transform the method above into an upsert: func (s *iamSvc) UpdateUser(ctx context.Context, in *iamv1.UpdateUserRequest) (*iamv1.User, error) {
// You must first validate and authorize the request but it is out of scope
now := timestamppb.Now()
user, err := s.usersRepo.GetUser(ctx, in.User.Name)
if err != nil {
if errors.CodeOf(err) != errors.CodeNotFound || !in.AllowMissing {
return nil, err
}
user = in.User
user.CreateTime = now
} else {
if err := fieldmask.Update(in.UpdateMask, user, in.User); err != nil {
// An error is thrown when an IMMUTABLE constraint is violated
return nil, errors.Wrap(err, errors.CodeInvalidArgument, "invalid update mask")
}
// user.CreateTime is not updated because of the OUTPUT_ONLY constraint
}
user.UpdateTime = now
if err := s.usersRepo.SaveUser(ctx, user); err != nil {
return nil, err
}
return user, nil
} As you can see, the new behavior of the Hoping to see this implemented one day, I wish you a great day. |
Hey there, picking up on this thread. Reading through the field behaviour AIP about immutable fields it says:
To me this means that the decision is left up to the service author to either ignore those fields or throw an error if a caller provides them. With this in mind I'd like to add a new validation function to check if immutable fields are set during an update, similar to What do you think? |
I put up a PR to implement the new validation function in #180 |
This issue has been open for 365 days with no activity. Marking as stale. |
Hello,
The AIP-203 specification defines custom behavior for updates using field masks :
(google.api.field_behavior) = OUTPUT_ONLY
should be ignored(google.api.field_behavior) = IMMUTABLE
should raise an error when the field is modifiedAt the moment, these behaviors are not taken into account by the fieldmask module and I think that it would be nice if it was supported.
What do you think about adding it in the
fieldmask.Update(mask *fieldmaskpb.FieldMask, dst, src proto.Message)
function ?The text was updated successfully, but these errors were encountered: