datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

Support readOnly and writeOnly openapi properties

Open m-vellinga opened this issue 2 years ago • 7 comments

Is your feature request related to a problem? Please describe. OpenAPI allows you to set a readOnly & writeOnly for fields to be able to reuse schemas for get and post for instance. See docs for more information. Would be nice to also support this, makes things a lot more "dry" on the spec side of things.

Describe the solution you'd like Since Pydantic does not support read/write only fields a possible solution could be to generate 2 versions of the same schema one with and one without the read/write only field.

Describe alternatives you've considered Alternative would be to define 2 different schemas in the openapi spec instead

m-vellinga avatar Mar 11 '22 14:03 m-vellinga

@m-vellinga Thank you for suggesting the feature. How do you control read/write in the pydantic world? Could you please tell the detail clearly?

koxudaxi avatar Apr 16 '22 17:04 koxudaxi

@koxudaxi What is possible to have in pydantic is allow_mutation Field constraint (default is True). And this is my use case, I also need to be able to set allow_mutation=False for some fields in generated pydantic models.

Now how we can define it in JSON Schema:

  1. readOnly

    • Pros:
      • It is already in JSON Schema specification
    • Cons:
      • Misleading name, at least according to samuelcolvin. He didn't agree to generate readOnly when generating JSON Schema from pydantic models, you can see in those two comments: https://github.com/samuelcolvin/pydantic/pull/2196#discussion_r550794426 https://github.com/samuelcolvin/pydantic/pull/2196#discussion_r550794616 This is reverted commit: https://github.com/samuelcolvin/pydantic/pull/2196/commits/521d254e400f588a2c48bdea7c38bc092dfd32c3#diff-c7021feccdf7c6e5a107ebfb58d3d553f2e30ab82be8acc88738c031f032b1ccL281
  2. immutable

    • Pros:
      • is more clear compared to readOnly, at least according to samuelcolvin
    • Cons:
      • not yet in JSON Schema specification
    • proposed here: https://github.com/json-schema-org/json-schema-vocabularies/issues/31
    • also proposed for OpenAPI-Specification: https://github.com/OAI/OpenAPI-Specification/issues/2720
  3. createOnly

    • suggested here: https://github.com/OAI/OpenAPI-Specification/issues/2720#issuecomment-925184694

However please also read all comments here: https://github.com/OAI/OpenAPI-Specification/issues/2720 It seems that choosing right name for it is really not easy...

Overall I'm not sure about correct decision here. Samuelcolvin clearly would chose immutable, but I'm not sure if he is right. I think that names in JSON Schema and in pydantic doesn't need to match, because they doesn't represent the same things. But I'm not sure, I need to probably think about it more...


For now we can just choose any name of those and change it later when this feature will be added to JSON Schema specification.

karolzlot avatar May 10 '22 04:05 karolzlot

Worth reading: chapter in JSON Schema specification about "readOnly" and "writeOnly": https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.4

karolzlot avatar May 10 '22 04:05 karolzlot

Ok, after writing this comment with a table I came to conclusion that:

samuelcolvin is right and readOnly isn't a good choice.

From pydantic's point of view both createAndRead and createOnly are ok and both should be coverted to pydantic's allow_mutation=False, but I think until we have official specification about at least one of those, we can just use immutable, because from pydantic's point of view it it the one most intuitive.

karolzlot avatar May 10 '22 04:05 karolzlot

Ok, after thinking more about this I changed my mind. I think the decision to have only readOnly and writeOnly in JSON Schema specification is right.

It's just that often more than 1 schema is needed.

From the point of view of pydantic, readOnly in schema should mean allow_mutation=False in pydantic. In my opinion samuelcolvin should allow to generate readOnly from pydantic fields with allow_mutation=False when generating schema from them.

karolzlot avatar May 10 '22 05:05 karolzlot

I think read/write-only properties are more about if they're allowed in object. Read-only property should be only allowed in a response model, so there should be validation for the request model that would forbid it Also, the property should be optional even if it's required, so a read-only property can be None in response object and vice versa

rafalkrupinski avatar Aug 15 '22 12:08 rafalkrupinski

Plus-one on this request. Currently every endpoint in my API has to have three separate schemas, for get, post, and patch. This makes development of our product far more complicated than it has to be, for those fields being missing. The complexity of our API is reaching a point where DMCG is choking on it for versions >= 18, meaning we're blocked on Pydantic 2 and FastAPI 100.

I don't even need them to be immutable in pydantic, I just need the system to know that if a property is readOnly it is only allowed in responses, and if it's writeOnly it's only allowed in request bodies.

mattholden avatar Jul 11 '23 16:07 mattholden