JamesMessinger / swagger-server

No longer maintained. Please use https://github.com/BigstickCarpet/swagger-express-middleware
MIT License
149 stars 47 forks source link

Wrapped response #11

Closed edubinin closed 9 years ago

edubinin commented 9 years ago

Hi, just wanted to set up a local swagger mocking service to develop my API specification and decided to use your module :) Not sure if thats bug or no, but here are the details: I want to wrap some model definitions in swagger response, so contrary to the petstore examples, I want to have my responses in following format:

{
  "data": {
  "id": 0,
  "username": "johndoe",
  "firstName": "john",
  "lastName": "doe",
  "email": "jdoe@acme.com",
  "password": "string",
  "phone": "1233451",
  "userStatus": 0
  },
  "status": "success"
}

instead of just:

{
  "id": 0,
  "username": "johndoe",
  "firstName": "john",
  "lastName": "doe",
  "email": "jdoe@acme.com",
  "password": "string",
  "phone": "1233451",
  "userStatus": 0
}

My problem is that I tried to achive this in different ways, for example creating the definitions for the wrapper of my models, and feed that definition as an response schema, however I get the original model back in the response. Any clue on what I am doing wrong here ?

I am using this version -> "swagger-server": "^1.0.0-alpha" Thanks

JamesMessinger commented 9 years ago

Can you post your Swagger file, so I can take a look? What you're trying to do is supported, so it should work.

Here's a demonstration, using the PetStore example... I'm modifying the /pets/{petName} GET operation, wrapping the "pet" response with a wrapper object, similar to your example:

  /pets/{petName}:
    parameters:
      - $ref: "#/parameters/petName"

    get:
      description: Returns a pet by name
      operationId: findPetByName
      responses:
        default:
          description: Returns the pet data
          schema:
            type: object                # this is the wrapper object
            properties:
              status:                   # status message
                type: string
                default: success
              data:                     # the actual pet data
                $ref: pet
edubinin commented 9 years ago

Here is the excerpt from my api spec(which I adjusted per your recommendations):

swagger: '2.0'
info:
  version: "0.0.2"
  title: test
  description: example for wrapped response

# the domain of the service
host: localhost

# array of all schemes that your API supports
schemes:
  - https
# will be prefixed to all paths
basePath: /api/v1

consumes:
  - application/json
produces:
  - application/json

definitions:
  Item:
    required:
    - id
    - name
    - taxPercentage
    - archived
    - createdAt
    - updatedAt

    allOf:
    - $ref: '#/definitions/NewItem'
    properties:
      archived:
        type: boolean
        description: soft deletion
        # default: false
      createdAt:
        type: string
        format: dateTime
        description: timestamp create date
        # default: 2000-04-16
      updatedAt:
        type: string
        format: dateTime
        description: timestamp update date

  NewItem:
    required:
    - name
    - taxPercentage
    - cost

    properties:
      id:
        type: integer
        description: Unique item identifier
      name:
        type: string
        description: item name
      description:
        type: string
        description: item long description
      code:
        type: string
        description: item code.
      cost:
        type: number
        format: float
        description: item cost which will be used in quote calculations
      taxPercentage:
        type: integer
        description: tax percentage value to apply to the item during quote calculations

paths:
  /items:
    get:
      description: |
        The Items endpoint returns information about all items.
      responses:
        default:
          description: Returns the pet data
          schema:
            $ref: '#/definitions/Item'
        200:
          description: Succesful Response. Return Array
          schema:
            type: array
            items:
              $ref: '#/definitions/Item'
        500:
          description: Error Response
    post:
      description: |
        The Items endpoint create new item.
      parameters:
        - name: item_object
          in: body
          description: item object
          required: true
          schema:
            type: object
            $ref: '#/definitions/NewItem'
      responses:
        200:
          description: Succesful Response
          schema:
            type: object
            properties:
              status:
                type: string
                default: 'sucess'
              data:
                $ref: '#/definitions/Item'
        500:
          description: Error Response

sample input (POSTed to the items endpoint):

{
  "name":"So12313a 42\" TV Set",
  "description":"Sony 133313 V-Series KDL-42V4100 42-Inch 1080p LCD HDTV",
  "cost":499.10,
  "taxPercentage":5
}

server response I got:

{"name":"So12313a 42\" TV Set","description":"Sony 133313 V-Series KDL-42V4100 42-Inch 1080p LCD HDTV","cost":499.1,"taxPercentage":5,"id":8780000132071424,"status":"sucess"}
JamesMessinger commented 9 years ago

Ah, I see the problem. Swagger Server doesn't currently understand "allOf", so it doesn't know that Item "inherits" from NewItem. This feature is on the to-do list for sure, but to make it work for now, the response type must match the parameter type exactly.

So, in your example, if you change the response type from Item to NewItem, it works.

post:
  description: |
    The Items endpoint create new item.
  parameters:
    - name: item_object
      in: body
      description: item object
      required: true
      schema:
        type: object
        $ref: '#/definitions/NewItem'        # Parameter type is "NewItem"
responses:
  200:
    description: Succesful Response
    schema:
      type: object
      properties:
        status:
          type: string
          default: 'sucess'
        data:
          $ref: '#/definitions/NewItem'      # Response type is "NewItem"
edubinin commented 9 years ago

Thank you for your help, it works now