naz / swagger-express-validator

Lightweight requrest/response validation middleware based on swagger/OpenAPI schema
MIT License
56 stars 24 forks source link

Body not validated #45

Closed DrakaSAN closed 5 years ago

DrakaSAN commented 5 years ago

bin/test.ts:

import express, { Application } from 'express';
import bodyParser from 'body-parser';
import YAML from 'yaml';
import { readFileSync } from 'fs';
import swaggerValidator from 'swagger-express-validator';
import pino from 'pino';
const logger = pino();

function getSchema(): any {
    return YAML.parse(
        readFileSync('./doc/openapi.yaml', 'utf-8')
    );
}

export function getApp(): Application {
    const app = express();

    app.use(bodyParser.json());

    app.use(swaggerValidator({
        schema: getSchema(),
        validateRequest: true,
        requestValidationFn: (): void => {
            logger.info('This is never logged');
        }
    }));

    app.post('/test', (req: express.Request, res: express.Response): void => {
        logger.info('This should not be logged, yet is');
        res.json({ status: 'ok' });
    });

    return app;
}

getApp().listen(7331);
logger.info('Listening');

doc/openapi.yaml:

openapi: "3.0.0"
info:
  title: Test
  version: 1.0.0
paths:
  /test:
    post:
      operationId: test
      summary: test
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Test"
      responses:
        '200':
          description: |-
            200 response
          content:
            application/json:
              schema: 
                $ref: "#/components/schemas/AppStatus"
        '500':
          description: |-
            500 response
          content:
            application/json:
              schema: 
                $ref: "#/components/schemas/AppStatus"
components:
  schemas:
    Test:
      required:
        - foo
        - bar
      properties:
        foo:
          type: number
        bar:
          type: array
          items:
            type: number
    AppStatus:
      required:
        - status
      properties:
        status:
          type: string
          enum:
            - ok
            - ko
        details:
          type: object
          additionalProperties: true

package.json:

{
  "name": "test",
  "version": "1.0.0",
  "author": "D219",
  "description": "test",
  "license": "WTFPL",
  "main": "bin/test.ts",
  "scripts": {
    "compile": "tsc -b --verbose",
    "start": "npm run compile && node built/bin/test.js | npx pino-pretty"
  },
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "pino": "^5.12.6",
    "swagger-express-validator": "^1.0.0",
    "yaml": "^1.6.0"
  },
  "devDependencies": {
    "@types/body-parser": "^1.17.0",
    "@types/express": "^4.17.0",
    "@types/node": "^12.0.8",
    "@types/pino": "^5.8.8",
    "@types/swagger-express-validator": "0.0.0",
    "@types/yaml": "^1.0.2",
    "pino-pretty": "^3.2.0",
    "source-map-support": "^0.5.12",
    "ts-node": "^8.2.0",
    "typescript": "^3.5.1"
  }
}

tsconfig.json:

  "compilerOptions": {
    "target": "es2018",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    "outDir": "./built",                        /* Redirect output structure to the directory. */
    "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    "strict": true,                           /* Enable all strict type-checking options. */
    "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
    "esModuleInterop": true,                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "resolveJsonModule": true
  }
}

Start the server with npm start, call it with curl --request POST --url http://127.0.0.1:7331/test --header 'content-type: application/json' --data '{}'

Body is missing all properties, yet the validator log nothing nor throw any error.

This look similar to issue 30.

kibertoad commented 5 years ago

@D219 You are using OpenAPI 3.0.0. I don't think this library supports that. https://www.npmjs.com/package/express-openapi-validate or https://www.npmjs.com/package/express-ajv-swagger-validation would work better.

DrakaSAN commented 5 years ago

express-openapi-validate indeed support OpenAPI 3, thanks for the tip.