JamesMessinger / swagger-server

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

Serving arrays? #10

Closed SteveNewhouse closed 8 years ago

SteveNewhouse commented 9 years ago

Hi there (apologies for bombarding w/questions recently, been exploring Swagger for our team and stumbled upon your tools).

I'm running into an issue where the mock output for a particular endpoint doesn't include any properties that are arrays.

Here's a partial example

  # ...
  /assignments/{assignmentId}:
    get:
      description: |
        Gets a specific `Assignment` by id.
      parameters:
        - $ref: '#/parameters/fields'
        - $ref: '#/parameters/assignmentId'
      responses:
        200:
          description: OK.
          schema:
            title: Assignment
            $ref: '#/definitions/Assignment'

######

definitions:
  Assignment:
    type: object
    properties:
      id:
        type: integer
        format: int64
      title:
        type: string
      description:
        type: string
      specialInstructions:
        type: string
      desiredSkills:
        type: string    
      pricing:
        $ref: '#/definitions/Pricing'
      messages:
        type: array
        items:
          $ref: '#/definitions/Message'
      payment:
        $ref: '#/definitions/Payment'
    example:
      id: 8374620983
      title: Haircut
      description: Please give me a haircut.
      specialInstructions: No buzzer, only scissors.  No hair gel either.
      desiredSkills: Barber, Styling

Pricing:
    type: object
    properties:
      flatPrice:
        type: number
        minimum: 0
      perHour:
        type: number
        minimum: 0
      maxHours:
        type: integer
        minimum: 0
      perAdditionalHour:
        type: number
        minimum: 0
      maxAdditionalHours:
        type: integer
        minimum: 0
      perUnit:
        type: number
        minimum: 0
      maxUnits:
        type: integer
        minimum: 0
    example:
      perHour: 25.00
      maxhours: 5
      perAdditionalHour: 15.00
      maxAdditionalHours: 2

  Message:
    type: object
    required:
      - text
    properties:
      sentDate:
        type: integer
        format: int64
      text:
        type: string
      createdBy:
        type: string
      isPrivate:
        type: boolean
      isPrivileged:
        type: boolean
    example:
      sentDate: 1438183874
      text: Hello there!
      createdBy: Bob Loblaw
      isPrivate: false
      isPrivileged: true 

This results in the following, which includes all the top-level example fields, as well as the example fields for the referenced Pricing model, but doesn't show any Messages data. Any idea how to get some array objects to show, even if it just repeats the same ones?

{
  "id": 8374620983,
  "title": "Haircut",
  "description": "Please give me a haircut.",
  "specialInstructions": "No buzzer, only scissors.  No hair gel either.",
  "desiredSkills": "Barber, Styling",
  "pricing": {
    "perHour": 25,
    "maxhours": 5,
    "perAdditionalHour": 15,
    "maxAdditionalHours": 2
  }
}
JamesMessinger commented 9 years ago

Hmmmm... it works fine for me. Am I missing something? Here's the full YAML that I used:

  swagger: "2.0"
  info:
    version: 1.0.0
    title: Swagger Petstore
    description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
    termsOfService: http://helloreverb.com/terms/
    contact:
      name: Wordnik API Team
      email: foo@example.com
      url: http://madskristensen.net
    license:
      name: MIT
      url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT

  host: localhost
  basePath: /api
  schemes:
    - http
  consumes:
    - application/json
  produces:
    - application/json

  paths:
    /assignments/{assignmentId}:
      put:
        description: foo
        parameters:
          - name: body
            in: body
            required: true
            description: foo
            schema:
              $ref: '#/definitions/Assignment'
        responses:
          201:
            description: ok
      get:
        description: |
          Gets a specific `Assignment` by id.
        responses:
          200:
            description: OK.
            schema:
              title: Assignment
              $ref: '#/definitions/Assignment'

  definitions:
    Assignment:
      type: object
      properties:
        id:
          type: integer
          format: int64
        title:
          type: string
        description:
          type: string
        specialInstructions:
          type: string
        desiredSkills:
          type: string    
        pricing:
          $ref: '#/definitions/Pricing'
        messages:
          type: array
          items:
            $ref: '#/definitions/Message'
      example:
        id: 8374620983
        title: Haircut
        description: Please give me a haircut.
        specialInstructions: No buzzer, only scissors.  No hair gel either.
        desiredSkills: Barber, Styling

    Pricing:
      type: object
      properties:
        flatPrice:
          type: number
          minimum: 0
        perHour:
          type: number
          minimum: 0
        maxHours:
          type: integer
          minimum: 0
        perAdditionalHour:
          type: number
          minimum: 0
        maxAdditionalHours:
          type: integer
          minimum: 0
        perUnit:
          type: number
          minimum: 0
        maxUnits:
          type: integer
          minimum: 0
      example:
        perHour: 25.00
        maxhours: 5
        perAdditionalHour: 15.00
        maxAdditionalHours: 2

    Message:
      type: object
      required:
        - text
      properties:
        sentDate:
          type: integer
          format: int64
        text:
          type: string
        createdBy:
          type: string
        isPrivate:
          type: boolean
        isPrivileged:
          type: boolean
      example:
        sentDate: 1438183874
        text: Hello there!
        createdBy: Bob Loblaw
        isPrivate: false
        isPrivileged: true 

I then sent a PUT request to http://localhost:8000/api/assignments/5 with the following body:

{
  "id": 123,
  "title": "hello world",
  "pricing": {
    "flatPrice": 123
  },
  "messages": [
    {
      "text": "hi there"
    },
    {
      "text": "nevermind"
    }
  ]
}

I then sent a GET request to http://localhost:8000/api/assignments/5, and got back the same JSON data that I had PUT, including the messages array.

JamesMessinger commented 9 years ago

Just FYI - I'm leaving for vacation tomorrow morning, so I may not be able to reply for a week or so.

SteveNewhouse commented 9 years ago

Thank you. In the example I gave, I didn't have to do a PUT first-- I was wondering if there was a way to get arrays to populate with example data without PUTing it there myself first.

That said- I didn't actually realize the PUT would work automatically either-- that is cool.

Enjoy your vacation and thanks for your responsiveness!

JamesMessinger commented 9 years ago

Hi. I'm back from vacation, and catching up on things.

If you don't want to add a PUT operation to your API, but you want your GET operation to return data, then you'll need to pre-populate your API with data. You can do this via the DataStore API. Here's some sample code.

SteveNewhouse commented 9 years ago

It seems like, to the end of the project goal of "fully-functional mock API with zero code", it might be a good enhancement to auto-generate array contents when none are explicitly provided through the DataStore API. If you like, you could have an "x-auto-generate" field or something to give the user control... I could look into this if you could point me in the right direction.

-S

JamesMessinger commented 9 years ago

Yeah, this feature is on the to-do list, but it'll take a lot of thought and design before we start implementing it. For the current version of Swagger Server, we're just focusing on providing mock implementions rather than mock data.

SteveNewhouse commented 8 years ago

Just to be clear here (reading this over, I don't think I was) -- I am mostly interested in the system attempting to mock array data in cases where an example is provided in the array item's model... It appears that when you have an array, even if the model for the array items has an example, it won't generate a mock output array.

In my example above, it'd be ideal if the response object had a "messages" field with one item in it-- the Message schema example.

Seems not a far stretch from current behavior (sans "array").

JamesMessinger commented 8 years ago

Isn't that what we already implemented in this pull-request?

SteveNewhouse commented 8 years ago

For whatever reason, this does not seem to work for me. Does it work for you if you reference an array item by schema, and that schema has an example output? In my case, the referenced array is not included in the mock data output.

-S

On Mon, Oct 5, 2015 at 2:32 PM, James Messinger notifications@github.com wrote:

Isn't that what we already implemented in this pull-request https://github.com/BigstickCarpet/swagger-express-middleware/pull/12?

— Reply to this email directly or view it on GitHub https://github.com/BigstickCarpet/swagger-server/issues/10#issuecomment-145624560 .

JamesMessinger commented 8 years ago

@SteveNewhouse - Yes, it works for me. The key is that you need to include an example array item. So, the full example for the Assignment model would be:

definitions:
  Assignment:
    type: object
    properties:
      ...
    example:
      id: 8374620983
      title: Haircut
      description: Please give me a haircut.
      specialInstructions: No buzzer, only scissors.  No hair gel either.
      desiredSkills: Barber, Styling
      messages:
        - $ref: '#/definitions/Message/example'

Now if you send a GET request to http://localhost:8000/api/assignments/5, and there is no Assignment resource with an ID of 5, then the example object will be returned — including the sample message.

SteveNewhouse commented 8 years ago

That was the issue--- thank you very much!

On Thu, Oct 8, 2015 at 12:20 PM, James Messinger notifications@github.com wrote:

@SteveNewhouse https://github.com/SteveNewhouse - Yes, it works for me. The key is that you need to include an example array item. So, the full example for the Assignment model would be:

definitions: Assignment: type: object properties: ... example: id: 8374620983 title: Haircut description: Please give me a haircut. specialInstructions: No buzzer, only scissors. No hair gel either. desiredSkills: Barber, Styling messages:

  • $ref: '#/definitions/Message/example'

Now if you send a GET request to http://localhost:8000/api/assignments/5, and there is no Assignment resource with an ID of 5, then the example object will be returned — including the sample message.

— Reply to this email directly or view it on GitHub https://github.com/BigstickCarpet/swagger-server/issues/10#issuecomment-146599971 .

JamesMessinger commented 8 years ago

Closing, since this is resolved. Please re-open if it's still an issue