yapkm01
yapkm01

Reputation: 3751

OpenAPI Parser (Light-4J) not working on "oneOf" criteria

Following is the schema.

Example 1)

components:
  schemas:
    GroupHeader114: <-- clause 1
      type: object
      properties:
        Authstn:
          type: object
          oneOf:
            - type: object
              properties:
                Cd:
                  type: string
                  enum:
                    - AUTH
                    - FDET
            - type: object
              properties:
                Prtry:
                  type: string
                  enum:
                    - ABC
                    - DDD

Payload:

{
       “GroupHeader114”: {
               “Authstn”: {
                    “Cd”: “AUTH”,
                    “Prtry”: “DDD”
               }
        }
}

Results: Validation passed when it should not since it meets criteria of both schema. There seems to be bugs in the parser or validator.

Example 2)

components:
  schemas:
    GroupHeader114: <-- clause 1
      type: object
      properties:
        GroupHeader114:
          type: object
          properties:
            Authstn:
              type: array
              maxItems: 2
              items:
                 $ref: '#.components/schemas/Authorisation1Choice'

    Authorisation1Choice:
      oneOf:
        - $ref '#components/schemas/AuthorisationCodeCd'
        - $ref '#components/schemas/Max128TextPrtry'

    Max128Text:
      type: string
      minLength: 1
      maxLength: 128

    Max128TextPrtry:
      type: object
      properties:
        Prtry:
          $ref: '#components/schemas/Max128Text'

    Authorisation1Code:
      type: string
      enum:
        - AUTH
        - FDET
        - FSUM
        - ILEV

    Authorisation1CodeCd:
     type: object
     properties:
       Cd:
         $ref: '#components/schemas/Authorisation1Code'

Payload:

{   
       “GroupHeader114”: {   
               “Authstn”: [   
              {   
                    “Cd”: “AUTH”   
               }   
        }   
}   

I am getting schema validation error saying requestBody.GroupHeader114.Authstn[0]: should be valid to one and only one of the schemas.

Appreciate any help.
Tx

ps: Light-4J - 2.0.10

Upvotes: 0

Views: 133

Answers (3)

Jeremy Fiel
Jeremy Fiel

Reputation: 3307

You have quite a few issues with your syntax. All references within the same schema must begin with an anchor(#) pointing to the root of the document and followed by a forward slash(/).

openapi: 3.0.3
info:
  title: my api
  version: 1.0.0
paths:
  '/some_endpoint':
    get:
      description: my api service
      responses:
        '200':
          $ref: '#/components/responses/GroupHeader114Response'
components:
  responses:
    GroupHeader114Response:
      description: OK
      content:
        'application/json':
          schema:
            $ref: '#/components/schemas/GroupHeader114'
          examples:
            GroupHeader114_Authorisation1CodeCd_Example:
              $ref: '#/components/examples/GroupHeader114_Authorisation1CodeCd_Example'
            GroupHeader114_Max128TextPrtry_Example:
              $ref: '#/components/examples/GroupHeader114_Max128TextPrtry_Example'
  examples:
    GroupHeader114_Authorisation1CodeCd_Example:
      summary: my example response
      value: { "GroupHeader114": { "Authstn": [ { "Cd": "AUTH" } ] } }
    GroupHeader114_Max128TextPrtry_Example:
      summary: my example response
      value: { "GroupHeader114": { "Authstn": [ { "Prtry": "AUTH" } ] } }
  schemas:
    GroupHeader114:
      type: object
      properties:
        GroupHeader114:
          type: object
          properties:
            Authstn:
              type: array
              maxItems: 2
              items:
                $ref: '#/components/schemas/Authorisation1Choice'
    Authorisation1Choice:
      oneOf:
      - $ref: '#/components/schemas/Authorisation1CodeCd'
      - $ref: '#/components/schemas/Max128TextPrtry'

    Max128Text:
      type: string
      minLength: 1
      maxLength: 128

    Max128TextPrtry:
      type: object
      additionalProperties: false
      properties:
        Prtry:
          $ref: '#/components/schemas/Max128Text'

    Authorisation1Code:
      type: string
      enum:
      - AUTH
      - FDET
      - FSUM
      - ILEV
    Authorisation1CodeCd:
      type: object
      additionalProperties: false
      properties:
        Cd:
          $ref: '#/components/schemas/Authorisation1Code'

I'm not clear on the last request. Currently, the schema only allows one or the other, not both.

should have either object Authorisation1Code or Max128Text and both.

Upvotes: 0

Jeremy Fiel
Jeremy Fiel

Reputation: 3307

It's a similar situation with example2. The mapping key entry in schemas is only an identifier of that schema. As you can see, it can be labeled anything, GroupHeader114 or A or B or Yap, the schema defined inside of that mapping entry is what the validation uses against the data instance.

components:
  schemas:
    GroupHeader114:
      oneOf: 
      - $ref '#components/schemas/A'
    A:
     type: object
     properties:
       Cd:
         type: string
         enum:
           - AUTH
           - FDET

If you're looking at the ref as a location identifier, it's pointing to the A schema defined in the components/schemas map.

Your data instance would not be

{
  "A": {
    "Cd": "AUTH"
  }
}

It would only be this because the schema definition is the contents of that key.

{
  "Cd": "AUTH"
}

Upvotes: 0

Jeremy Fiel
Jeremy Fiel

Reputation: 3307

Your schema is missing the top level node.

components:
  schemas:
    GroupHeader114: # <-- this is the mapping key for the schema, not the top level json node. 
      type: object
      properties:
        GroupHeader114:
          type: object
          properties:
            Authstn:
              type: object
              oneOf:
                - type: object
                  properties:
                    Cd:
                      type: string
                      enum:
                        - AUTH
                        - FDET
                - type: object
                  properties:
                    Prtry:
                      type: string
                      enum:
                        - ABC
                        - DDD

the reason it was not flagging an error is because GroupHeader114 was not validated. It was ignored.

EDIT: more explanation:

in OpenAPI context, the components/schemas is a map of entries. The mapping key for the schema you defined is GroupHeader114, but that keyword is not part of the actual schema in the way you are expecting, it's just a pointer to that particular schema.

If your data instance was this, it would work the way you expect.

{
  "Authstn": {
    "Cd": "AUTH",
    "Prtry": "DDD"
  }
}

Upvotes: 0

Related Questions