- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 780
Description
Description
When an API object has a field that is required but has readOnly: true, a request containing an object without that field fails to validate.
OpenAPI spec says:
You can use the
readOnlyandwriteOnlykeywords to mark specific properties as read-only or write-only. This is useful, for example, when GET returns more properties than used in POST – you can use the same schema in both GET and POST and mark the extra properties asreadOnly.readOnlyproperties are included in responses but not in requests, [...]
If a
readOnlyorwriteOnlyproperty is included in the required list, required affects just the relevant scope – responses only or requests only. That is, read-only required properties apply to responses only, [...]
This is a regression from Connexion 2.x.
Expected behaviour
Object validates successfully.
Actual behaviour
Object fails to validate, because it is missing a read-only field:
ERROR:connexion.validators.json:Validation error: 'objectId' is a required property
ERROR:connexion.middleware.exceptions:BadRequestProblem(status_code=400, detail="'objectId' is a required property")
Presumably Connexion 3.x fails to use jsonschema validation properly here.
Steps to reproduce
- Use the openapi.yaml and testcontroller.py from below
- Start with connexion run openapi.yaml --stub
- Attempt to do the following request: PUT .../objects/45d2847a-ed55-440a-bfa7-5e759d0d671f, with body
{
    "name": "abc"
}
Minimal example:
openapi.yaml
openapi: 3.0.3
info:
  title: test
  version: '1.0'
paths:
  '/objects/{objectId}':
    parameters:
      - schema:
          type: string
          format: uuid
        name: objectId
        in: path
        required: true
    put:
      summary: Create or update object
      operationId: object_put
      x-openapi-router-controller: testcontroller
      responses:
        '200':
          description: OK - Object updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Object'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Object'
components:
  schemas:
    Object:
      title: BaseObject
      type: object
      properties:
        objectId:
          type: string
          format: uuid
          readOnly: true
        name:
          type: string
      required:
      - objectId
      - name
testcontroller.py
from connexion import FlaskApp, request
app = FlaskApp(__name__)
def object_put(objectId, body):
    return {"objectId": objectId, **body}
app.add_api("openapi.yaml")
Additional info:
Output of the commands:
- python --version- Python 3.11.3
 
- pip show connexion | grep "^Version\:"- Version: 3.0.6