Gi60s / openapi-enforcer

Apache License 2.0
94 stars 22 forks source link

Response bodies not validating correctly #153

Closed dabernathy89 closed 1 year ago

dabernathy89 commented 1 year ago

Minimal reproduction here:

https://stackblitz.com/edit/node-lhzu7w?file=index.js

I can't seem to get response bodies to validate correctly. Perhaps I'm doing something wrong, but I've written the code almost exactly as the example shown here: https://openapi-enforcer.com/guide/#producing-a-valid-result

  const openapi = await Enforcer('./openapi.yml', {
    componentOptions: {
      exceptionSkipCodes: ['WRES001'],
    },
  });

  const [req] = openapi.request({
    method: 'POST',
    path: '/locations',
    body: { name: 'foo' },
  });

  const body = {
    uuid: ['blah'],
    name: 123,
  };
  const headers = {};
  // No matter what is passed in as the body, `error` is undefined
  const [res, error] = req.response(201, body, headers);

  console.log({ error });
Gi60s commented 1 year ago

I wanted to let you know that I'd seen the issue. I can't take a look at it right now, but I will take a look this evening (probably in about 10-12 hours). I'm guessing it's probably something pretty simple.

Thanks for the stackblitz too. That will help a lot for debugging this.

Gi60s commented 1 year ago

I see the problem. First I'll explain how to correct it, then I'll explain why it didn't fail previously.

How to Correct

Your body is slightly malformed. It should look like this:

const body = {
    data: {
      uuid: ['blah'],
      name: 123,
    }
  };

Once corrected, the console output looks like this:

{
  error: [ EnforcerException: Response invalid
      at: body > data
        at: uuid
          Expected a string. Received: [blah]
        at: name
          Expected a string. Received: 123 ]
}

Why Didn't It Fail Previously

The OpenAPI Specification for the Schema Object says

The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.

If we look up that specification we'll find that by default value for additionalProperties is true.

This is important, especially when you're defining a schema that is made up of multiple schemas, such as using the OpenAPI specification's allOf schemas functionality.

The reason your previous code did not produce errors is that there were no uuid nor name properties defined at the top level of the response schema. Only a data property was defined, so the uuid and name properties were allowed and with no schema defined for them they defaulted to passing validation

If you have any other questions around this feel free to ask. I'll close the issue, but you can still comment.

Happy coding!

dabernathy89 commented 1 year ago

D'oh! Thank you for the thorough response. Makes perfect sense.