Ошибка проверки Swagger - request.path НЕ ДОЛЖНА иметь дополнительных свойств - PullRequest
0 голосов
/ 24 апреля 2020

Это относится ко всем путям, в которых есть параметр user_id (т. Е. Все, кроме postUser). Когда я тестирую эти конечные точки с помощью Postman, я получаю 400 с сообщением «request.path НЕ должно иметь дополнительных свойств». Я использую пакет в качестве промежуточного ПО для проверки сваггеров в моих маршрутах следующим образом. Например: router.get ('/: userId', swaggerValidator.validate, contextExtractor, getUserById);

Где сначала идет проверка сваггера, затем 2 других промежуточных ПО. Пакет можно найти здесь: https://www.npmjs.com/package/openapi-validator-middleware

Если я уроню промежуточное ПО валидатора, все хорошо, и код работает, как и ожидалось.

См. Файл чванства ниже:

swagger: "2.0"
info:
  description: "This is an external Users service API. It manages any user info in the systems, including its personal data, address and additional needed values, all in favour of maintaining the updated and relevant data which is either business-related or provided when a user requests any action in the system."
  version: "1.0.0"
  title: "Users Micro Service"
basePath: "/v1"
tags:
  - name: "User Details"
    description: "A user's data and info, supporting CRUD operations"
  - name: "User Addresses"
    description: "All the addresses data of a user"
  - name: "User Address"
    description: "A user's single address data"
schemes:
  - "https"
  - "http"
consumes:
  - "application/json; charset=utf-8"
produces:
  - "application/json; charset=utf-8"
paths:
  '/users':
    post:
      tags:
        - "User Details"
      summary: "Create a new user in the system"
      operationId: "postUser"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - in: "body"
          name: "User Request"
          description: "The user's data to be stored"
          required: true
          schema:
            $ref: "#/definitions/user_request"
      responses:
        201:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        409:
          description: "Conflict - email already exists"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
  '/users/:user_id':
    get:
      tags:
        - "User Details"
      summary: "Get the user's data by its Id"
      operationId: "getUserById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
      responses:
        200:
          description: "Successful operation"
          schema:
            $ref: "#/definitions/user_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "User was not found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    patch:
      tags:
        - "User Details"
      summary: "Modify an existing user's data"
      operationId: "patchUserById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - in: "body"
          name: "User data"
          description: "The user's data to be modified"
          required: true
          schema:
            $ref: "#/definitions/user_patch_request"
      responses:
        200:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    put:
      tags:
        - "User Details"
      summary: "Modify an existing user's data by overriding it"
      operationId: "putUserById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - in: "body"
          name: "User data"
          description: "The user's data to be modified"
          schema:
            $ref: "#/definitions/user_put_request"
      responses:
        200:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
  '/users/:user_id/addresses':
    post:
      tags:
        - "User Address"
      summary: "Create a new address for a user and store it in the database"
      operationId: "postAddress"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - in: "body"
          name: "Address Request"
          description: "The address data to be stored"
          required: true
          schema:
            $ref: "#/definitions/put_user_address_request"
      responses:
        201:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_address_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    get:
      tags:
        - "User Addresses"
      summary: "Get all addresses of a user by its id"
      operationId: "getAddresses"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
      responses:
        200:
          description: "Successful Operation"
          schema:
            type: "array"
            items:
              $ref: "#/definitions/user_address_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "User not found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
  '/users/:user_id/addresses/:address_id':
    get:
      tags:
        - "User Address"
      summary: "Get a user's address by its Id"
      operationId: "getAddressById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - $ref: "#/parameters/address_id"
      responses:
        200:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_address_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    put:
      tags:
        - "User Address"
      summary: "Modify a user's existing address data by overriding it"
      operationId: "putAddressById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - $ref: "#/parameters/address_id"
        - in: "body"
          name: "Address"
          description: "The address's data to be modified"
          schema:
            $ref: "#/definitions/put_user_address_request"
      responses:
        200:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_address_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    patch:
      tags:
        - "User Address"
      summary: "Add or modify to an existing user's address data"
      operationId: "patchAddressById"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - $ref: "#/parameters/address_id"
        - in: "body"
          name: "Address"
          description: "The address data to be modified"
          schema:
            $ref: "#/definitions/patch_user_address_request"
      responses:
        200:
          description: "Successful Operation"
          schema:
            $ref: "#/definitions/user_address_resource"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
    delete:
      tags:
        - "User Address"
      summary: "Deletes a user's address by its Id"
      operationId: "deleteAddressById"
      produces:
        - "text/plain; charset=utf-8"
      parameters:
        - $ref: "#/parameters/company_user_id"
        - $ref: "#/parameters/company_request_id"
        - $ref: "#/parameters/user_id"
        - $ref: "#/parameters/address_id"
      responses:
        204:
          description: "Successful Operation - No content"
        400:
          description: "Bad Request"
          schema:
            $ref: "#/definitions/error"
        404:
          description: "Not Found"
          schema:
            $ref: "#/definitions/error"
        500:
          description: "Internal Error"
          schema:
            $ref: "#/definitions/error"
definitions:
  user_request:
    type: "object"
    description: "User request body"
    required:
      - email_address
      - terms_accepted
      - first_name
      - last_name
    properties:
      email_address:
        type: "string"
        description: "The user's email address (unique)"
      first_name:
        type: "string"
        description: "The user's first name"
      last_name:
        type: "string"
        description: "The user's last name"
      marketing_opt_in_accepted:
        type: "boolean"
        description: "Boolean to determine if the user has opted in for marketing"
        default: false
      terms_accepted:
        type: "boolean"
        description: "Boolean to determine if the user has accepted the site's terms"
      phone_number:
        type: "string"
        description: "The user's phone number"
      additional_values:
        type: "object"
        x-example: {
          "key1" : "value1",
          "key2" : "value2"
        }
  user_put_request:
    required:
      - email_address
      - first_name
      - last_name
    type: "object"
    properties:
      email_address:
        type: "string"
        description: "The user's email address"
      first_name:
        type: "string"
        description: "The user's first name"
      last_name:
        type: "string"
        description: "The user's last name"
      marketing_opt_in_accepted:
        type: "boolean"
        description: "Boolean to determine if the user has opted in for marketing (default: false)"
        default: false
      phone_number:
        type: "string"
        description: "The user's phone number"
      additional_values:
        type: "object"
        x-example: {
          "key1" : "value1",
          "key2" : "value2"
        }
  user_patch_request:
    type: "object"
    properties:
      email_address:
        type: "string"
        description: "The user's email address"
      first_name:
        type: "string"
        description: "The user's first name"
      last_name:
        type: "string"
        description: "The user's last name"
      marketing_opt_in_accepted:
        type: "boolean"
        description: "Boolean to determine if the user has opted in for marketing"
        default: false
      phone_number:
        type: "string"
        description: "The user's phone number"
      additional_values:
        type: "object"
        x-example: {
          "key1": "value1",
          "key2": "value2"
        }
  user_resource:
    type: "object"
    allOf: [$ref: '#/definitions/user_request', $ref: '#/definitions/updatable_object_metadata']
    required:
      - date_terms_accepted
    properties:
      date_terms_accepted:
        type: "string"
        format: "date-time"
        description: "Time stamp of when the user has accepted the site's terms"
  put_user_address_request:
    required:
      - address_line_1
      - city
      - postal_code
      - country_code
    properties:
      nickname:
        type: "string"
        description: "A human-readable nickname for the address"
        x-example: "HOME"
      address_line_1:
        type: "string"
        description: "A text line containing street name and number"
        x-example: "3 Florentin Street"
      address_line_2:
        type: "string"
        description: "A text line containing apartment number, floor, entrance, etc."
        x-example: "372A, 7th floor"
      address_line_3:
        type: "string"
        description: "A text line containing additional delivery instructions"
        x-example: "Please knock on the door instead of ringing the bell"
      country_code:
        type: "string"
        description: "3-letter alpha-code for a country (capital letters only)"
        x-example: "GBR"
      state_province:
        type: "string"
        description: "The state or province in which the address is in"
        x-example: "Yorkshire"
      city:
        type: "string"
        description: "The city in which the address is in"
        x-example: "London"
      postal_code:
        type: "string"
        description: "The address' zipcode"
        x-example: "EC1A 1BB"
      address_type:
        type: "string"
        description: "The type of which the address belongs to"
        enum: ["RESIDENTIAL", "OFFICE", "HOTEL", "BUSINESS"]
        x-example: "OFFICE"
  patch_user_address_request:
    type: "object"
    properties:
      nickname:
        type: "string"
        description: "A human-readable nickname for the address"
        x-example: "HOME"
      address_line_1:
        type: "string"
        description: "A text line containing street name and number"
        x-example: "3 Florentin Street"
      address_line_2:
        type: "string"
        description: "A text line containing apartment number, floor, entrance, etc."
        x-example: "372A, 7th floor"
      address_line_3:
        type: "string"
        description: "A text line containing additional delivery instructions"
        x-example: "Please knock on door instread of ringing bell"
      country_code:
        type: "string"
        description: "3-letter alpha-code for a country (capital letters only)"
        x-example: "GBR"
      state_province:
        type: "string"
        description: "The state or province in which the address is in"
        x-example: "Yorkshire"
      city:
        type: "string"
        description: "The city in which the address is in"
        x-example: "London"
      postal_code:
        type: "string"
        description: "The address' zipcode"
        x-example: "EC1A 1BB"
      address_type:
        type: "string"
        description: "The type of which the address belongs to"
        enum: ["RESIDENTIAL", "OFFICE", "HOTEL", "BUSINESS"]
        x-example: "OFFICE"
  user_address_resource:
    type: "object"
    required:
      - id
      - address_line_1
      - address_created
      - address_updated
      - city
      - country_code
      - postal_code
    properties:
      id:
        type: "string"
        format: "uuid"
        description: "The address Id"
        x-example: "23cfeebf-45ef-4446-9f2f-017894fc806e"
      nickname:
        type: "string"
        description: "A human-readable nickname for the address"
        x-example: "HOME"
      address_line_1:
        type: "string"
        description: "A text line containing street name and number"
        x-example: "3 Florentin Street"
      address_line_2:
        type: "string"
        description: "A text line containing apartment number, floor, entrance, etc."
        x-example: "372A, 7th floor"
      address_line_3:
        type: "string"
        description: "A text line containing additional delivery instructions"
        x-example: "Please knock on door instread of ringing bell"
      country_code:
        type: "string"
        description: "3-letter alpha-code for a country (capital letters only)"
        x-example: "GBR"
      state_province:
        type: "string"
        description: "The state or province in which the address is in"
        x-example: "Yorkshire"
      city:
        type: "string"
        description: "The city in which the address is in"
        x-example: "London"
      postal_code:
        type: "string"
        description: "The address' zipcode"
        x-example: "EC1A 1BB"
      address_type:
        type: "string"
        description: "The type of which the address belongs to"
        enum: ["RESIDENTIAL", "OFFICE", "HOTEL", "BUSINESS"]
        x-example: "OFFICE"
      address_created:
        type: "string"
        format: "date-time"
        description: "Timestamp of when the address was created"
        x-example: "2017-08-19 12:17:55 -0400"
      address_updated:
        type: "string"
        format: "date-time"
        description: "Timestamp of when the address was updated"
        x-example: "2017-08-19 12:17:55 -0400"
      user_id_created:
        type: "string"
        format: "uuid"
        description: "The user id which created the address"
        x-example: "1df65272-a44e-4b8c-887d-b645ec9136a0"
      user_id_updated:
        type: "string"
        format: "uuid"
        description: "The user id which last updated the address"
        x-example: "1df65272-a44e-4b8c-887d-b645ec9136a0"
  object_metadata: 
    type: "object"
    required: 
      - id
      - created_time
      - user_id_created
      - updated_time
    properties: 
      id: 
        type: "string"
        format: "uuid"
      created_time: 
        type: "string"
        format: "date-time"
      user_id_created: 
        type: "string"
        format: "uuid"
      updated_time: 
        type: "string"
        format: "date-time"
  updatable_object_metadata: 
    type: "object"
    allOf: 
      - $ref: '#/definitions/object_metadata'
    required: 
      - user_id_updated
    properties: 
      user_id_updated: 
        type: "string"
        format: "uuid"
  error:
    type: "object"
    required:
      - "message"
    properties:
      message:
        type: "string"
        description: "The error's message"
      more_info:
        type: "string"
        description: "More info if it exists"
parameters:
  company_user_id:
    name: "x-company-user-id"
    in: "header"
    description: "The User Id"
    required: true
    type: "string"
    format: "uuid"
    x-example: "15325c58-a41a-4105-bae1-99fa3a8bedc7"
  company_request_id:
    name: "x-company-request-id"
    in: "header"
    description: "The Request Id"
    required: true
    type: "string"
    format: "uuid"
    x-example: "5134366e-ce9e-42ea-921b-ebe11257a773"
  user_id:
    name: "user_id"
    in: "path"
    description: "The user's Id"
    required: true
    type: "string"
    format: "uuid"
    x-example: "fc1e2015-f408-465a-af97-6621a3754764"
  address_id:
    name: "address_id"
    in: "path"
    required: true
    type: "string"
    format: "uuid"
    x-example: "08ed91c3-ce96-4c93-b75a-5a0c6eb8d13c"


1 Ответ

0 голосов
/ 24 апреля 2020

Ваш пример использует нотацию :param для параметров пути, которые OpenAPI не поддерживает. OpenAPI использует обозначение {param}. Вам нужно изменить определение API, чтобы использовать {param} вместо :param.

Неправильно:

paths:
  '/users':
    ...
  '/users/:user_id':
    ...
  '/users/:user_id/addresses':
    ...
  '/users/:user_id/addresses/:address_id':
    ...

Правильно:

paths:
  '/users':
    ...
  '/users/{user_id}':
    ...
  '/users/{user_id}/addresses':
    ...
  '/users/{user_id}/addresses/{address_id}':
    ...
...