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

chore!: improve decoding of required fields #254

Merged
merged 34 commits into from
Sep 16, 2024
Merged

chore!: improve decoding of required fields #254

merged 34 commits into from
Sep 16, 2024

Conversation

EvanHahn
Copy link
Contributor

@EvanHahn EvanHahn commented Sep 11, 2024

A required field, confusingly, should probably be marked optional in the protobuf. That way, we can throw errors when decoding. See #252 for more details.

This change:

  • Updates .proto files to mark all required fields with our custom required tag
  • Updates .proto files to mark most required fields as optional, so we can throw errors when decoding
  • Throw errors when decoding if a field is missing

I tested this end-to-end.

Closes #252.

[Gregor rightly pointed out that this value is synced][0]. Given that
this value is currently unused on the frontend, we should remove it.

[0]: digidem/comapeo-core#751 (comment)
A required field, confusingly, should probably be marked *optional* in
the protobuf. That way, we can throw errors when decoding. See [#252]
for more details.

This change:

- Updates `.proto` files to mark all required fields with our custom
  `required` tag
- Updates `.proto` files to mark most required fields as `optional`, so
  we can throw errors when decoding
- Throw errors when decoding if a field is missing

I tested this end-to-end.

[#252]: https://github.com/digidem/mapeo-schema/issues/252
@gmaclennan
Copy link
Member

I have a question about enums: without optional then if the field is not present, it will be decoded to unspecified. With optional we kind of have two "unspecified" states of the enum. Because we have already gone to the effort of adding unspecified everywhere, I think maybe we could follow a practice of enum fields never being optional? And require their presence base on unspecified.

@gmaclennan
Copy link
Member

I realise there is confusing behaviour here: you could write data with an empty string for a required field and it will type check, and it will not complain when writing to the DB, you will just never see that data record again...

@EvanHahn
Copy link
Contributor Author

I have a question about enums: without optional then if the field is not present, it will be decoded to unspecified. With optional we kind of have two "unspecified" states of the enum. Because we have already gone to the effort of adding unspecified everywhere, I think maybe we could follow a practice of enum fields never being optional? And require their presence base on unspecified.

Fixed the one violation of this in 931f473. (Manually checked every occurrence of git grep -E "optional [A-Z]" proto/.)

I realise there is confusing behaviour here: you could write data with an empty string for a required field and it will type check, and it will not complain when writing to the DB, you will just never see that data record again...

Good point. Gave all required strings a minLength in 0bd5ab4. (Required a small tweak to the way we do codegen because of a bug in Ajv.)

@EvanHahn
Copy link
Contributor Author

This causes breakages in @comapeo/core which I'll look at tomorrow.

Base automatically changed from remove-isinitialproject to main September 12, 2024 15:24
Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

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

Did an initial review of this because I'm not sure when I can get back to it later.

I think the barrier for a "required" field at the protobuf level should be a bit higher. I think it should be "the app can't function without this field", because the action we take is fairly "drastic" which is to ignore the record altogether. There are a few fields I have highlighted that I think could be made optional. I think also the config metadata should also maybe be all optional - I feel like in general metadata should be a "optional if you have it" field.

VersionId should have index as required, and decode code should check that. I think we we require it on the JSON side.

There are a few follow up things I think which are not essential for MVP, such as checking docIds are not zero-length, and I think we should also look at distinguishing "write" vs "read" types for the app-side, mainly for enums - you should not be able to write an enum which is "unspecified" or "unrecognized", but the read type shoudl have them.

proto/preset/v1.proto Outdated Show resolved Hide resolved
proto/preset/v1.proto Outdated Show resolved Hide resolved
proto/deviceInfo/v1.proto Outdated Show resolved Hide resolved
src/lib/decode-conversions.ts Show resolved Hide resolved
src/lib/decode-conversions.ts Outdated Show resolved Hide resolved
schema/deviceInfo/v1.json Outdated Show resolved Hide resolved
@EvanHahn
Copy link
Contributor Author

I think I got this working, but I'm going to test it end-to-end to make sure things still work.

@EvanHahn
Copy link
Contributor Author

Running into issues getting this to work in @comapeo/core and beyond. I'll look more on Monday.

@EvanHahn
Copy link
Contributor Author

This PR was getting a little too large for me, so I'm starting to split it into smaller ones:

EvanHahn and others added 16 commits September 16, 2024 16:07
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
Co-Authored-By: Gregor MacLennan <gmaclennan@digital-democracy.org>
@EvanHahn
Copy link
Contributor Author

Gregor and I paired on this so I'm going to merge.

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

Successfully merging this pull request may close these issues.

A new take on protobuf optional fields...
3 participants