swagger-api / swagger-node

Swagger module for node.js
http://swagger.io
Apache License 2.0
3.97k stars 585 forks source link

Validation fails when returning a json number #427

Open chrisegner opened 8 years ago

chrisegner commented 8 years ago

The validator does not decode the json-encoded value of the response unless it is an object or an array. This leads it to produce a validation failure for a valid response.

(Incidentally, it appears that the HTTP response is also not properly formed according to curl. Let me know if you'd like a separate bug report for that.)

Error (server-side, includes some debug prints I've added):

  swagger-tools:middleware:metadata GET /random/int +2m
  swagger-tools:middleware:metadata   Is a Swagger path: true +0ms
  swagger-tools:middleware:metadata   Is a Swagger operation: true +0ms
  swagger-tools:middleware:metadata   Processing Parameters +1ms
  swagger-tools:middleware:metadata     min +0ms
  swagger-tools:middleware:metadata       Type: integer (format: int64) +0ms
  swagger-tools:middleware:metadata       Value provided: false +0ms
  swagger-tools:middleware:metadata       Value: undefined +1ms
  swagger-tools:middleware:metadata     max +0ms
  swagger-tools:middleware:metadata       Type: integer (format: int64) +0ms
  swagger-tools:middleware:metadata       Value provided: false +0ms
  swagger-tools:middleware:metadata       Value: undefined +0ms
  swagger-tools:middleware:security GET /random/int +0ms
  swagger-tools:middleware:security   Will process: yes +1ms
  swagger-tools:middleware:validator GET /random/int +1ms
  swagger-tools:middleware:validator   Will process: yes +0ms
  swagger-tools:middleware:validator   Request validation: +0ms
  swagger-tools:middleware:validator     Validation: succeeded +0ms
  swagger-tools:middleware:router GET /random/int +0ms
  swagger-tools:middleware:router   Will process: yes +0ms
  swagger-tools:middleware:router   Route handler: index_randomInteger +0ms
  swagger-tools:middleware:router     Missing: no +0ms
  swagger-tools:middleware:router     Ignored: no +0ms
  swagger-tools:middleware:router     Using mock: no +7ms
random randomInteger - req.swagger.params { min: 
   { path: [ 'paths', '/random/int', 'get', 'parameters', '0' ],
     schema: 
      { name: 'min',
        in: 'query',
        description: 'The minimum integer to return',
        required: false,
        type: 'integer',
        format: 'int64' },
     originalValue: undefined,
     value: undefined },
  max: 
   { path: [ 'paths', '/random/int', 'get', 'parameters', '1' ],
     schema: 
      { name: 'max',
        in: 'query',
        description: 'One larger than the maximum integer to return',
        required: false,
        type: 'integer',
        format: 'int64' },
     originalValue: undefined,
     value: undefined } }
random randomInteger - value 8199160169749457 function Number() { [native code] }
  swagger-tools:middleware:validator   Response validation: +2ms
  swagger-tools:middleware:validator     Response code: 200 +0ms
swagger validators - val 8199160169749457 function String() { [native code] }
  swagger-tools:middleware:validator     Validation: failed +0ms
  swagger-tools:middleware:validator   Reason: Not a valid int64 integer: 8199160169749457 +0ms
  swagger-tools:middleware:validator   Stack: +0ms
  swagger-tools:middleware:validator       at throwErrorWithCode (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:121:13) +0ms
  swagger-tools:middleware:validator       at validateTypeAndFormat (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:539:7) +0ms
  swagger-tools:middleware:validator       at Object.module.exports.validateSchemaConstraints (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:631:7) +0ms
  swagger-tools:middleware:validator       at validateValue (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-validator.js:117:16) +0ms
  swagger-tools:middleware:validator       at ServerResponse.res.end (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-validator.js:252:9) +0ms
  swagger-tools:middleware:validator       at ServerResponse.send (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/express/lib/response.js:205:10) +0ms
  swagger-tools:middleware:validator       at ServerResponse.json (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/express/lib/response.js:250:15) +0ms
  swagger-tools:middleware:validator       at randomInteger (/Users/cegner/Programming/swagger-trial/hello-world-express/api/controllers/random/index.js:17:9) +3ms
  swagger-tools:middleware:validator       at swaggerRouter (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-router.js:407:20) +0ms
  swagger-tools:middleware:validator       at swagger_router (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-node-runner/fittings/swagger_router.js:31:5) +0ms
Error: Response validation failed: not a valid int64 integer: 8199160169749457
    at throwErrorWithCode (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:121:13)
    at validateTypeAndFormat (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:539:7)
    at Object.module.exports.validateSchemaConstraints (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/lib/validators.js:631:7)
    at validateValue (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-validator.js:117:16)
    at ServerResponse.res.end (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-validator.js:252:9)
    at ServerResponse.send (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/express/lib/response.js:205:10)
    at ServerResponse.json (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/express/lib/response.js:250:15)
    at randomInteger (/Users/cegner/Programming/swagger-trial/hello-world-express/api/controllers/random/index.js:17:9)
    at swaggerRouter (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-tools/middleware/swagger-router.js:407:20)
    at swagger_router (/Users/cegner/Programming/swagger-trial/hello-world-express/node_modules/swagger-node-runner/fittings/swagger_router.js:31:5)

Request:

$ curl -v http://127.0.0.1:10010/random/int
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 10010 (#0)
> GET /random/int HTTP/1.1
> Host: 127.0.0.1:10010
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 500 Internal Server Error
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Content-Type: application/json
< Content-Length: 16
< ETag: W/"10-bk52XbTWOFDYeCCIdPrZ6A"
< Date: Thu, 25 Aug 2016 21:29:14 GMT
< Connection: keep-alive
< 
* Excess found in a non pipelined read: excess = 273, size = 16, maxdownload = 16, bytecount = 0
* Connection #0 to host 127.0.0.1 left intact
{"message":"Resp$

Files: swagger.yaml

swagger: "2.0"
info:
  version: "0.0.1"
  title: Hello World App
# during dev, should point to your local machine
host: localhost:10010
# basePath prefixes all resource paths 
basePath: /
# 
schemes:
  # tip: remove http to make production-grade
  - http
  - https
# format of bodies a client can send (Content-Type)
consumes:
  - application/json
# format of the responses to the client (Accepts)
produces:
  - application/json

paths:
  /random/int:
    $ref: ./api/controllers/random/int.swagger.yaml
  /swagger:
    x-swagger-pipe: swagger_raw

# complex objects have schema definitions
definitions:
  ErrorResponse:
    required:
      - message
    properties:
      message:
        type: string

./api/controllers/random/int.swagger.yaml

x-swagger-router-controller: index
get:
  description: Returns a random integer
  operationId: randomInteger
  parameters:
    - name: min
      in: query
      description: The minimum integer to return
      required: false
      type: integer
      format: int64
    - name: max
      in: query
      description: One larger than the maximum integer to return
      required: false
      type: integer
      format: int64
  responses:
    "200":
      description: Success
      schema:
        type: integer
        format: int64
    default:
      description: Error
      schema:
        $ref: "#/definitions/ErrorResponse"

controller snippet:

'use strict';

function randomInteger(req, res) {
    // variables defined in the Swagger document can be referenced using req.swagger.params.{parameter_name}
    console.log('random randomInteger - req.swagger.params', req.swagger.params);

    var min = req.swagger.params.min.value !== undefined ? req.swagger.params.min.value : 0;
    var max = req.swagger.params.max.value !== undefined ? req.swagger.params.max.value : Number.MAX_SAFE_INTEGER;
    var value = Math.floor(Math.random() * (max - min)) + min;

    console.log('random randomInteger - value', value, value.__proto__.constructor);

    res.json(value);
}

module.exports = {
    randomInteger: randomInteger,
};
sukrit007 commented 8 years ago

Just ran into the issue where response is not formatted correctly. It works for some exceptions, while it returns malformed json for others.