kogosoftwarellc / open-api

A Monorepo of various packages to power OpenAPI in node
MIT License
895 stars 237 forks source link

Validation error despite valid schema. #721

Closed pate313373 closed 2 years ago

pate313373 commented 3 years ago

Hi,

I'd really like to give open-api for express a chance. - The concept is very cool!

My code is this:

const express = require('express');
const openapi = require('express-openapi');
const v1UserService = require('./api/v1/services/userService');

const app = express();
openapi.initialize({
  app,
  // NOTE: If using yaml you can provide a path relative to process.cwd() e.g.
  // apiDoc: './api-v1/api-doc.yml',
  apiDoc: './api/v1/doc/testproject.v1.yaml',
  dependencies: {
    userService: v1UserService
  },
  paths: './api/v1/paths'
});

app.listen(3000);

However, when I try to run my .yaml I run into the following error:

express-openapi: Validating schema before populating paths
express-openapi: validation errors [
  {
    "keyword": "type",
    "dataPath": "",
    "schemaPath": "#/type",
    "params": {
      "type": "object"
    },
    "message": "should be object"
  }
]
E:\projects\test-openapi\node_modules\openapi-framework\dist\index.js:100
                throw new Error(this.loggingPrefix + "args.apiDoc was invalid.  See the output.");
                ^

Error: express-openapi: args.apiDoc was invalid.  See the output.

I can confirm, that my .yaml file is valid:

openapi: 3.0.0
info:
  title: testproject
  version: '1.0'
  contact:
    name: me
    email: me@me.me
    url: ''
  license:
    name: closed source
  description: This is the API service for testproject.
servers:
  - url: 'http://localhost:1337'
    description: dev
paths:
  /users:
    get:
      summary: bulk create users
      tags: []
      responses:
        '200':
          description: OK
          headers: {}
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
              examples: {}
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      operationId: getUser
      description: Get a User based on the query provided in the body.
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                username:
                  type: string
                active:
                  type: string
                firstName:
                  type: string
                lastName:
                  type: string
                email:
                  type: string
            examples:
              Query for username:
                value:
                  user: frank
              Query for status:
                value: {}
    parameters: []
    put:
      summary: ''
      operationId: updateUsers
      responses:
        '200':
          description: OK
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/User'
      description: Updates an array of users. The provided objects will be replaced entirely.
    patch:
      summary: ''
      operationId: archiveUsers
      responses:
        '200':
          description: OK
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      description: |-
        This operation allows to manage the archived state of the object.
        Use this operation instead of delete.
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  _id:
                    type: string
                  archived:
                    type: boolean
    post:
      summary: ''
      operationId: createUsers
      responses:
        '201':
          description: Created
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/User'
      description: Bulk create Users.
  /users/login:
    post:
      summary: ''
      operationId: login
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
      description: ''
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
                password:
                  type: string
              required:
                - username
                - password
      security: []
  /users/logout:
    post:
      summary: ''
      operationId: logout
      responses:
        '200':
          description: OK
      description: ''
  /register:
    post:
      summary: ''
      operationId: registerUser
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
  /flights:
    get:
      summary: bulk read Flights (paged)
      tags: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  pages:
                    $ref: '#/components/schemas/Pages'
                  flights:
                    type: array
                    items:
                      $ref: '#/components/schemas/Flight'
          headers: {}
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      operationId: getFlights
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                dep:
                  type: array
                  items:
                    type: string
                arr:
                  type: array
                  items:
                    type: string
                flt:
                  type: string
                fromStd:
                  type: string
                toStd:
                  type: string
                fromSta:
                  type: string
                toSta:
                  type: string
      parameters:
        - schema:
            type: integer
            default: 0
          in: query
          name: page
          description: 'The page of results to be returned (indexed: 0).'
        - schema:
            type: integer
            default: 20
          in: query
          name: pageSize
          description: The maximum number of results per page.
      description: ''
    post:
      summary: bulk create Flights
      operationId: createFlights
      responses:
        '201':
          description: Created
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/Flight'
    put:
      summary: bulk replace Flights
      operationId: replaceFlights
      responses:
        '200':
          description: OK
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      description: Updates an array of flights. The provided objects will be replaced entirely.
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/Flight'
    patch:
      summary: bulk set archived state of Flights
      operationId: archiveFlight
      responses:
        '200':
          description: OK
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  _id:
                    type: string
                  archived:
                    type: boolean
      description: |-
        This operation allows to manage the archived state of the object.
        Use this operation instead of delete.
components:
  schemas:
    User:
      title: User
      type: object
      x-examples:
        example-1:
          id: string
          user: string
          password: string
          active: string
          firstName: string
          lastName: string
          email: string
      properties:
        _id:
          type: string
          readOnly: true
        username:
          type: string
        password:
          type: string
        active:
          type: boolean
        firstName:
          type: string
        lastName:
          type: string
        email:
          type: string
        archived:
          type: boolean
      required:
        - username
        - password
    Flight:
      title: Flight
      type: object
      properties:
        _id:
          type: string
          readOnly: true
        flt:
          type: string
        callsign:
          type: string
        dep:
          type: string
        arr:
          type: string
        std:
          type: string
        sta:
          type: string
        etd:
          type: string
        eta:
          type: string
        atd:
          type: string
        ata:
          type: string
        archived:
          type: boolean
      required:
        - flt
        - callsign
        - dep
        - arr
        - std
        - sta
    Pages:
      title: Pages
      type: object
      properties:
        pageNumber:
          type: integer
          description: The index of the returned page.
        pageSize:
          type: integer
          description: The number of elements per page.
        totalPages:
          type: integer
          description: The total number of pages.
        totalElements:
          type: integer
          description: The total number of elements available.
  securitySchemes:
    Authorization:
      type: http
      scheme: bearer
  responses: {}
  parameters: {}
security:
  - Authorization: []

I'm wondering if there's a way to get a more verbose output to understand why the initialization fails.

Kind regards

tricoos commented 2 years ago

@pate313373 When I enter your code on https://editor.swagger.io/ I get validation errors.

When I do this with my code I don't get validation errors but I'm still running into the same problem as you with this lib, unfortunately.

tricoos commented 2 years ago

I found the reason for my error message: the file simply did not exist at the path defined in apiDoc. Could the devs please add a single if to give a better error message like The path ... specified in apiDoc does not exist ?

pate313373 commented 2 years ago

@pate313373 When I enter your code on https://editor.swagger.io/ I get validation errors.

When I do this with my code I don't get validation errors but I'm still running into the same problem as you with this lib, unfortunately.

Thx tricoos! I created the definition with Postman, that's why I thought it must be correct...

jsdevel commented 2 years ago

can this be closed?

pate313373 commented 2 years ago

Sure, thx. However, more verbose error output would be highly appreciated

jsdevel commented 2 years ago

@pate313373 please feel free to submit a PR!