Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Response validation does not work at all #43

Open
avdv opened this issue Oct 29, 2021 · 2 comments
Open

Response validation does not work at all #43

avdv opened this issue Oct 29, 2021 · 2 comments

Comments

@avdv
Copy link

avdv commented Oct 29, 2021

Hi.

I am trying to validate my API responses, but no matter what is send as a response, there is no indication of an error.

Steps to reproduce:

  1. git clone [email protected]:bug-hunters/oas3-tools.git
  2. cd oas3-tools
  3. npm install
  4. npm run build
  5. cd examples/petstore
  6. npm install
  7. enable response validation:
    diff --git a/examples/petstore/example.js b/examples/petstore/example.js
    index d33681d..f4d0fcd 100644
    --- a/examples/petstore/example.js
    +++ b/examples/petstore/example.js
    @@ -21,6 +21,7 @@ var options = {
             errorLimit: 400
         },
         openApiValidator: {
    +        validateResponses: true,
     
             validateSecurity: {
                 handlers: {
    
  8. change the getPetById response such that it is invalid:
    diff --git a/examples/petstore/services/PetService.js b/examples/petstore/services/PetService.js
    index fc835a3..0874c0d 100644
    --- a/examples/petstore/services/PetService.js
    +++ b/examples/petstore/services/PetService.js
    @@ -62,7 +62,7 @@ exports.getPetById = function(petId) {
             var examples = {};
             examples['application/json'] = {
                 'photoUrls' : [ 'photoUrls', 'photoUrls' ],
    -            'name' : 'doggie',
                 'id' : 0,
                 'category' : {
                     'name' : 'name',
    
  9. npm start
  10. curl localhost:8080/pet/0 -H api_key:test
{
  "photoUrls": [
    "photoUrls",
    "photoUrls"
  ],
  "id": 0,
  "category": {
    "name": "name",
    "id": 6
  },
  "tags": [
    {
      "name": "name",
      "id": 1
    },
    {
      "name": "name",
      "id": 1
    }
  ],
  "status": "available"
}

I would expect to receive an error in this case.

Using the express-openapi-validator directly instead works:

const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const http = require('http');
const PetService = require('./services/PetService');
const OpenApiValidator = require('express-openapi-validator');

const port = 8080;
const app = express();
const apiSpec = path.join(__dirname, 'api/petstore.yaml');

// 1. Install bodyParsers for the request types your API will support
app.use(express.urlencoded({ extended: false }));
app.use(express.text());
app.use(express.json());

// Optionally serve the API spec
app.use('/spec', express.static(apiSpec));

//  2. Install the OpenApiValidator on your express app
app.use(
  OpenApiValidator.middleware({
    apiSpec,
    validateResponses: true, // default false
  }),
);

// 3. Add routes
app.get('/pet/:petId', async (req, res, next) => {
    const body = await PetService.getPetById(req.params.petId + 0);
    res.send(body);
});

http.createServer(app).listen(port);
console.log(`Listening on port ${port}`);
$ node serve.js
Listening on port 8080
Internal Server Error: .response should have required property 'name'
    at ResponseValidator._validate (/home/claudio/github/oas3-tools/examples/petstore/node_modules/express-openapi-validator/dist/middlewares/openapi.response.validator.js:154:19)
    at /home/claudio/github/oas3-tools/examples/petstore/node_modules/express-openapi-validator/dist/middlewares/openapi.response.validator.js:42:33
    at ServerResponse.json_hook (/home/claudio/github/oas3-tools/examples/petstore/node_modules/express-openapi-validator/dist/framework/modded.express.mung.js:35:24)
    at ServerResponse.send (/home/claudio/github/oas3-tools/examples/petstore/node_modules/express/lib/response.js:158:21)
    at /home/claudio/github/oas3-tools/examples/petstore/serve.js:31:9
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
@MartinSunal
Copy link

Hi,

I experienced the same issue and I investigated it a bit further.

Short answer:

Use res.send() or res.json() methods to respond with data and response validation will work as expected.

Long answer:

Response validation is hooked on res.json() method in express-openapi-validator:
https://github.com/cdimascio/express-openapi-validator/blob/3e803b586170e4fc079faedc2eb219276429826e/src/framework/modded.express.mung.ts#L59

Current implementation of the Pet example is using utils.writeJson(res, response):

utils.writeJson(res, response);

and utils.writeJson(res, response) calls response.end(payload):
response.end(payload);

That means hooked res.json() is never called so validation is not executed.

Also Express suggest to use res.json() or res.send() instead of res.end() when returning data.
https://expressjs.com/en/api.html#res.end

Keep in mind, that validation will work only with JSON response.

I also tested, that it is possible to enable response validation which will remove all fields not mentioned in openAPI schema:

validateResponses: {
  removeAdditional: 'all',
}

@MartinSunal
Copy link

to my previous answer:

I also tested, that it is possible to enable response validation which will remove all fields not mentioned in openAPI schema:

validateResponses: {
  removeAdditional: 'all',
}

There is a problem with response validation when removeAdditional: 'all' option is used in this case:

  1. OAS contains oneOf statement without discriminator
  2. express-openapi-validator and ajv used in oas3-tools do not understand discriminator
    oas3-tools v2.2.3 depends on express-openapi-validator ^4.4.3 (v4.13.5) which depends on ajv ^6.12.6 (6.12.6)

removeAdditional option is propagated to ajv which describes the problem here:
https://ajv.js.org/guide/modifying-data.html#removing-additional-properties
https://ajv.js.org/json-schema.html#discriminator

Solution could be to use express-openapi-validator version which supports discriminator:
Discriminator support in ajv was added in v8. Ajv v8 is used in express-openapi-validator v4.13.8 https://github.com/cdimascio/express-openapi-validator/commits/v4.13.8
I did not test express-openapi-validator v4.13.8 though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants