Skip to content

Request validation does not work correctly with discriminator  #80

@evgenykireev

Description

@evgenykireev

Discriminator property is not taken into account when validating request body.
Given example schema from https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
request body

{
  "pet_type": "Cat",
  "breed":    "Dingo",
  "bark":     true,
}

should not be valid, however it passes ValidateRequest.

Code to reproduce:

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/getkin/kin-openapi/openapi3"
	"github.com/getkin/kin-openapi/openapi3filter"
)

const testSchema = `openapi: 3.0.0
info:
  title: ''
  version: 0.0.1
paths:
  /:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
              discriminator:
                propertyName: pet_type

components:
  schemas:
    Pet:
      type: object
      required:
        - pet_type
      properties:
        pet_type:
          type: string
      discriminator:
        propertyName: pet_type

    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            breed:
              type: string
              enum: [Dingo, Husky, Retriever, Shepherd]
    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            hunts:
              type: boolean
            age:
              type: integer
`

func main() {
	payload := map[string]interface{}{
		"pet_type": "Cat",
		"breed":    "Dingo",
		"bark":     true,
	}

	p, _ := json.Marshal(payload)

	swagger, _ := openapi3.NewSwaggerLoader().LoadSwaggerFromData([]byte(testSchema))

	router := openapi3filter.NewRouter().WithSwagger(swagger)
	req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewReader(p))
	route, pathParams, _ := router.FindRoute(req.Method, req.URL)
	req.Header.Set("Content-Type", "application/json")

	requestValidationInput := &openapi3filter.RequestValidationInput{
		Request:    req,
		PathParams: pathParams,
		Route:      route,
	}

	err := openapi3filter.ValidateRequest(context.TODO(), requestValidationInput)
	if err == nil {
		fmt.Println("Valid")
	} else {
		fmt.Println("NOT valid")
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions