spot icon indicating copy to clipboard operation
spot copied to clipboard

Add examples for request and response body

Open mahirk opened this issue 4 years ago • 6 comments

Is your feature request related to a problem? Please describe. After https://github.com/airtasker/spot/pull/916 I was looking to add examples for the request and response body objects i.e.non parameter objects.

Describe the solution you'd like The OpenAPI spec defines the examples for this like:

examples:
          Jessica:
            value:
              id: 10
              name: Jessica Smith
          Ron:
            value:
              id: 20
              name: Ron Stewart

This is different than how we define examples for parameters. In the case of a body, the example is generated for the set of properties in a given schema.

Thinking about ways to satisfy that for a given body, there are two ways which this could be done, they both rely on the developer adding an example for every property and match the example names. I've provided only one of the ways below:

interface CreateUserRequest {
  /**
   * @example property-example-one
   * "Angela"
   * @example property-example-two
   * "Meena"
   */
  firstName: string;
  /**
   * @example property-example-one
   * "Kapoor"
   * @example property-example-two
   * "Shah"
   */
  lastName: string;
}

both of these would generate

examples:
          property-example-one:
            value:
              firstName: Angela
              lastName: Kapoor
          property-example-one:
            value:
              firstName: Meena
              lastName: Shah

mahirk avatar Oct 16 '20 03:10 mahirk

@lfportal My apologies for pulling you towards one more direction, I know there are several PRs/Issues open for you to look at. I am looking for any thoughts you have on this implementation as well since the examples here are much different than the examples in parameters.

mahirk avatar Oct 23 '20 06:10 mahirk

Spot should be cater for examples at any point where a type is defined or referenced. Asides from the existing header/path/query params, the following elements refer to types: body, interface / type(alias) and object properties. To be as flexible and accomodating as possible, I imagine the following syntax:

@endpoint({
  method: "POST",
  path: "/users"
})
class PostEndpoint {
  @request
  request(
    /**
     * @example request-example-one
     * {
     *   "name": "Gandalf"
     * }
     *
     * @example request-example-two
     * {
     *   "name": "Galadriel"
     * }
     */
    @body body: {
      /**
       * @example inline-schema-example
       * "Legolas"
       */
      name: String;
    }
  ) { }

  @response({ status: 201 })
  successResponse(
    /**
     * @example response-example-one
     * {
     *   "id": 1,
     *   "name": "Gandalf"
     * }
     *
     * @example response-example-two
     * {
     *   "id": 2,
     *   "name": "Galadriel"
     * }
     */
    @body body: UserBody
  ) { }
}

/**
 * @example user-body-example
 * {
 *   "id": 256,
 *   "name": "Gimli"
 * }
 *
 */
interface UserBody {
  /**
   * @example id-example
   * 512
   */
  id: Int32;
  /**
   * @example name-example
   * "Sauron"
   */
  name: String;
}

The OpenAPI equivalent being:

paths:
  /users:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: Legolas    # <-- example
            examples:
              request-example-one:    # <-- example
                value:
                  name: Gandalf
              request-example-one:    # <-- example
                value:
                  name: Galadriel    # <-- example
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserBody'
              examples:
                response-example-one:    # <-- example
                  value:
                    id: 1
                    name: Gandalf
                response-example-one:    # <-- example
                  value:
                    id: 2
                    name: Galadriel

# ...

components:
  schemas:
    UserBody:
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 512    # <-- example
        name:
          type: string
          example: Sauron    # <-- example
      example:    # <-- example
        id: 256
        name: Gimli

interface / type(alias) and object properties examples will likely be a bit more involved, so it's probably better to tackle just body examples for now.

lfportal avatar Oct 23 '20 14:10 lfportal

Hi @lfportal , since this is currently unassigned can I take this up ?

san-gh avatar Feb 12 '21 07:02 san-gh

Hi @lfportal , since this is currently unassigned can I take this up ?

@mahirk is this one you're currently actively tackling?

lfportal avatar Feb 12 '21 23:02 lfportal

hey @lfportal Sorry, I've been tied up on some other work, and I likely won't be able to get on some of this work until mid June. These and other should be open for pick up, I'll be back (and try bringing some more folks on this) as soon as possible :)

mahirk avatar Mar 15 '21 19:03 mahirk

@san-gh are you happy to pick this one up?

lfportal avatar Mar 19 '21 03:03 lfportal