Search code examples
jsonpswagger

How should I handle an application/javascript response type in Swagger?


I have a swagger app that works when JSON is returned, but not with JSONP. Success and fail cases are described further down.

It is worth noting that the exact controller code shown below works fine under vanilla node/express - the problem seems to occure when the response goes through the swagger response validator.

The snippet of controller code that handles the response is as follows:

retVal.success = true;
retVal.data = jsondata;
res.set('Content-Type', 'application/javascript');
res.jsonp(200, retVal);

swagger.yaml:

swagger: "2.0"
info:
  title: sometitle
  version: v1
host: localhost:3000
basePath: /
schemes:
  - http
consumes:
- application/json
- application/javascript
produces:
- application/json
- application/javascript
- text/javascript
paths:
  /loadallrepos:
    x-swagger-router-controller: loadallrepos
    get:
      summary: summary here...
      description: |
        description here...
      operationId: loadallrepos
      parameters:
        - name: callback
          in: query
          description: Passed by .ajax call for cross-domain requests
          required: false
          type: string
      responses:
        200:
          description: Success
          schema:
            $ref: "#/definitions/loadallreposResponse"
definitions:
  loadallreposResponse:
    type: object
    required:
      - success
      - data
    properties:
      success:
        type: boolean
      data:
        type: object
        required:
          - nextrefresh
        properties:
          nextrefresh:
            type: integer

If I make a request without the callback parameter, it works:

request: localhost:3000/loadallrepos

response:

{
      "success": true,
      "data": {
        "nextrefresh": 3439704
      }
}

If I turn it into a jsonp request though, it fails:

request: localhost:3000/loadallrepos?callback=jQuery111106460774131119251_1439402109118&_1439402109119

response:

{
    "message": "Response validation failed: value expected to be an array/object but is not",
    "failedValidation": true,
    "originalResponse": "typeof jQuery111106460774131119251_1439402109118 === 'function' && jQuery111106460774131119251_1439402109118({
  "success": true,
  "data": {
    "nextrefresh": 3442750
  }
});"
}

Again, this works under vanilla node/express. Any help is greatly appreciated!


Solution

  • JSONP APIs return a string of JavaScript. Your Swagger definition says your API returns an object defined at #/definitions/loadallreposResponse which is of type object. What happens is swagger-node/swagger-tools sees a type of object and attempts to use JSON.parse on the response body and fails. To support JSONP with Swagger, you need to make your response schema be of type string to avoid response validation failure.