Skip to content

required readOnly fields are required in request body when they shouldn't be #1907

Open
@sampoh0523

Description

@sampoh0523

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 readOnly and writeOnly keywords 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 as readOnly. readOnly properties are included in responses but not in requests, [...]

If a readOnly or writeOnly property 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

  1. Use the openapi.yaml and testcontroller.py from below
  2. Start with connexion run openapi.yaml --stub
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    PR welcomeWe would welcome and review a PR addressing this issuebug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions