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

Does readOnly actually do any validation? #473

Open
jpincas opened this issue Jun 7, 2024 · 1 comment
Open

Does readOnly actually do any validation? #473

jpincas opened this issue Jun 7, 2024 · 1 comment
Labels
question Further information is requested

Comments

@jpincas
Copy link

jpincas commented Jun 7, 2024

Quick question. Using the readOnly tag. I can see that it effectively removes the field from the documentation for POST/PATCH requests, but it doesn't actually seem to have any validatory effect.

To be specific. My struct has a field daysOld which is marked 'readOnly'. Although the field doesn't show in the docs, I can add it to a PATCH request and no error is raised and the field is effectively written to the server.

My expectation was that adding the 'readOnly' field would mean that if the field were included in a PATCH request, either an error would be raised or it would just be ignored. Perhaps I've missed something here? Thanks.

@danielgtaylor danielgtaylor added the question Further information is requested label Jun 12, 2024
@danielgtaylor
Copy link
Owner

@jpincas great question! This is somewhat complicated for a few reasons (isn't it always 😂...) There are really three scenarios for handling read-only fields:

  1. Ignore them. Huma doesn't care, and it's up to the service implementor to determine what to do with them. This is easy to implement and has no performance penalty but makes life harder when writing services. This makes round-trips of data easy.
  2. Return a validation error. Huma detects which fields are read-only, and if set in any PUT/POST/PATCH request it returns a 422. We use the same logic as defaults/resolvers to walk the incoming structure to determine if any value is non-zero. This has a small performance penalty but can be skipped for objects without read-only fields. This prevents round-trips from working.
  3. Zero the fields. Like defaults, we walk the incoming structure and explicitly set zero values for any read-only fields. This has the highest performance penalty and is tricky to implement, but doable.

One of the major scenarios I needed to efficiently support with Huma is round-tripping of data with read-only fields, for example think of a created date or updated date or some computed hash value in a field of the resource. So you need to be able to GET the resource, modify it in-place, then submit via PUT and have it just work.

For Huma v2 I wound up going with option 1: ignore read-only fields. This is simplest and gives the most flexibility in how to handle the incoming fields, but it does mean you need to be careful when writing your service. For example, when doing PUT we tend to either fetch any existing resource and copy over the read-only fields, or use partial update DB queries which ignore the read-only fields.

I'm happy to revisit this decision. It let me ship Huma v2 faster and keeps it easier to maintain, but if desired we can always add support for additional scenarios, and can probably do a better job of documenting this stuff instead of having it swimming around in my head 😄

Interesting side note: I actually had a Huma v1 PR for implementing each of these, see #63.

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

No branches or pull requests

2 participants