Search code examples
expressswaggeropenapiswagger-jsdocs

Swagger openapi 3.0.x empty body


I am trying to migrate my from swagger 2.0 to openapi 3.0.2 for my express api. The swagger definitions and paths are written in swagger-jsdoc. This should cause no problems because their documentation state that it can work with openapi 3.x as well as with swagger 2.0.

When adding openapi: 3.0.x to my swaggerDefinition the views look fine. However when trying to do a post request through the swagger views, the body is empty.

My swagger definition looks like this:

const swaggerOptions = {
    swaggerDefinition: {
        openapi: '3.0.2',
        info: {
            title: `Channels API`,
            description: "Channels API",
            version: "v1"
        },
        servers: [ {
            url: "http://127.0.0.1:3000",
            description: 'Local server'
        }],
    },
    apis: ['./routes/*.js'],
};

Now I have a file channels.js as a router: It has the following definition in it:

class Channel extends BaseRouter {
/**
* @swagger
*
* definitions:
*   channel:
*     type: object
*     tags:
*       - Channels
*     properties:
*       name:
*           type: string
*       global:
*           type: boolean
*     required:
*       - name
*/

constructor(app, version) {
    super(app, new ChannelCtrl(), version);
}

post() {
    /**
     * @swagger
     * /api/v1/channels:
     *  post:
     *      tags:
     *          - Channels
     *      name: Create
     *      produces:
     *          - application/json
     *      consumes:
     *          - application/json
     *      summary: Create new channel object
     *      parameters:
     *       - name: channel
     *         required: true
     *         in: body
     *         description: Fields of the channel object to be created
     *         type: object
     *         schema:
     *             $ref: '#/definitions/channel'
     *      responses:
     *          '200':
     *              description: Channel object has been created
     *              application/json:
     *                  schema:
     *                      $ref: '#/definitions/channel'
     */
    this.app.post(`/api/${this.version}/channels`, this.controller.create.bind(this.controller));
    return this;
}

Trying it with swagger 2.0 seems to work fine.. What am I missing?


Solution

  • In openapi 3.0.x they have replaced the parameters by requestBody as shown here https://swagger.io/docs/specification/describing-request-body/ So your file channels.js should look like this:

        class Channel extends BaseRouter {
    /**
    * @swagger
    *
    * definitions:
    *   channel:
    *     type: object
    *     tags:
    *       - Channels
    *     properties:
    *       name:
    *           type: string
    *       global:
    *           type: boolean
    *     required:
    *       - name
    */
    
    constructor(app, version) {
        super(app, new ChannelCtrl(), version);
    }
    
    post() {
        /**
         * @swagger
         * /api/v1/channels:
         *  post:
         *      tags:
         *          - Channels
         *      name: Create
         *      produces:
         *          - application/json
         *      consumes:
         *          - application/json
         *      summary: Create new channel object
         *      requestBody:
         *         content:
         *            application/x-www-form-urlencoded:
         *               schema:
         *                  type: object
         *                  properties:
         *                     field1:          # <!--- form field name
         *                        type: string
         *                     field2:          # <!--- form field name
         *                        type: string
         *      responses:
         *          '200':
         *              description: Channel object has been created
         *              application/json:
         *                  schema:
         *                      $ref: '#/definitions/channel'
         */
        this.app.post(`/api/${this.version}/channels`, this.controller.create.bind(this.controller));
        return this;
    }