Authress-Engineering / openapi-explorer

OpenAPI Web component to generate a UI from the spec.
Apache License 2.0
316 stars 42 forks source link

Request Body for content type multipart/form-data FORM not rendered #243

Closed neongrau closed 8 months ago

neongrau commented 8 months ago

I have endpoints that allow file uploads, for those multipart/form-data is required.

Under the "FORM" Tab next to "MODEL" the form controls should be shown.

Bildschirmfoto 2024-03-07 um 16 20 43 Bildschirmfoto 2024-03-07 um 16 20 52

But they are not, or rather almost always they are not shown. When clicking around sometimes (very rarely) they appear, but i cannot reproduce when they do appear.

Here is a reduced example spec.

Tested for validity

openapi-spec-validator public/api-docs/v4/develop.yaml
public/api-docs/v4/develop.yaml: OK
---
info:
  title: TESTING ONLY
  version: v4
  description: |
    ## This is a testing only spec.
    > DO NOT USE!
components:
  securitySchemes:
    Bearer:
      description: |
        # Token based authentication Header
        Authenticate and then copy the token into this field without the "Bearer " prefix.
      type: http
      scheme: bearer
  schemas:
    FacilityContentSerializer:
      type: object
      required:
      - content_type
      properties:
        id:
          type: string
          readOnly: true
          description: unique record id
        device_model_ids:
          type: array
          description: ids of device models this content is assigned to
          items:
            type: string
        content_type:
          type: string
          description: content type
          enum:
          - text
          - file
          - link
        category:
          type: string
          description: the category under which this content will be displayed when
            linked to device models
          enum:
          - model
          - service
          - technical
          - training
          - regulatory
        title:
          type: string
          description: title (only for text)
        content:
          type: string
          description: content (supports Markdown, only for text)
        url:
          type: string
          description: URL (only for link contents)
        resource:
          type: object
          additionalProperties:
            type: string
          description: |-
            oEmbed key/value pairs supplied by the remote service
            (optional, depending on support provided by the remote service,
            only for link contents)
          properties: {}
        name:
          type: string
          description: file name (only for file contents)
        document:
          type: string
          format: binary
          writeOnly: true
          description: multipart form data file to upload
        document_data_uri:
          type: string
          writeOnly: true
          description: base64 encoded file to upload
    meta:
      type: object
      description: Base and minimum information returned for every response under
        the `meta` key of the the JSON root
      required:
      - locale
      - msg
      properties:
        git_version:
          type: string
          description: backend version string
        total:
          type: number
          description: number of total records
        json_api_options:
          type: object
          properties:
            limit:
              type: number
              default: 10
              description: page size - maximum number of records returned in a request
            page:
              type: number
              default: 1
              description: the current page number
            fields:
              type: object
              description: if the request was sent with fields parameter (comma separated
                field names) this shows which fields were requested
              properties: {}
        locale:
          type: string
          default: en
          description: the currently selected locale
        msg:
          type: object
          description: info about the request
          required:
          - success
          - error
          properties:
            success:
              type: boolean
              default: true
              description: indicates successful requests
            message:
              type: string
              description: if unsuccessful contains a detailed error message
            error:
              type: string
              description: if unsuccessful contains an error name
              enum:
              - ''
              - argument_error
              - authorization_error
              - database_error
              - forbidden
              - general_error
              - gridfilter_error
              - invalid_file_error
              - maintenance
              - maintenance_readonly
              - malformed_csv_error
              - malformed_json
              - missing_tenant_context
              - not_a_sync_api_subscriber
              - object_id_invalid
              - record_not_found_error
              - smtp_syntax_error
              - subscription_expired
              - tenant_not_found
              - unauthenticated
              - unauthorized
              - unsupported_image_error
            error_details:
              nullable: true
              oneOf:
              - type: string
              - type: array
                items:
                  type: string
    relationships:
      type: object
      description: Optional listing of associated records if available
      additionalProperties:
        type: object
        description: key being the name of the relation
        required:
        - data
        properties:
          data:
            anyOf:
            - type: object
              required:
              - id
              - type
              properties:
                id:
                  type: string
                type:
                  type: string
              description: single relation reference in case of one-to-one
            - type: array
              description: array of relation references in case of one-to-many
              items:
                type: object
                required:
                - id
                - type
                properties:
                  id:
                    type: string
                  type:
                    type: string
    translations:
      type: object
      description: Key being a valid 2-digit (ISO-639-1) language code (lowercase)
        with corresponding language content as value
      additionalProperties:
        type: string
servers:
- url: "{protocol}://{defaultHost}"
  variables:
    protocol:
      default: https
    defaultHost:
      default: localhost.samedis.care
openapi: 3.0.3
paths:
  "/api/v4/tenants/{tenant_id}/facility_contents":
    post:
      summary: Create Facility Contents
      x-candos:
      - samedis-care/catalogs.tenant-writer
      x-model-type: FacilityContent
      x-record-type: facility_content
      description: "  This endpoint manages various contents that the facility\ncan
        assign to any device model (even on public ones)\nfor their own use (not publicly
        shared).\n\nThese contents can be either plain text, an uploaded document\nor
        a remote link (e.g. videos).\n\n---\n\nController: `Api::V4::Tenants::FacilityContentsController`\n\n---\n\nThis
        endpoint is limited to\n25\nrequests per 60 seconds.\n\nIf this limit is exhausted
        the server will return HTTP status 429 \nAnd a header `Retry-After` with the
        number of seconds the client's user \naccount needs to wait before the endpoint
        will allow further requests.\n\nClients using this endpoint should implement
        a delay handling to wait the given\nseconds before retrying and avoid repeating
        previous requests that finished\nsuccessfully.\n"
      tags:
      - Facility Contents
      security:
      - Bearer: []
      parameters:
      - name: tenant_id
        in: path
        required: true
        description: Facility Contents tenant_id
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  type: object
                  required:
                  - content_type
                  properties:
                    document:
                      type: string
                      format: binary
                      writeOnly: true
                      description: multipart form data file to upload
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                data[document]:
                  type: string
                  format: binary
                  writeOnly: true
                  description: multipart form data file to upload
          multipart/form-data:
            schema:
              type: object
              properties:
                data[document]:
                  type: string
                  format: binary
                  writeOnly: true
                  description: multipart form data file to upload
      responses:
        '200':
          description: FacilityContent created
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                description: Single endpoints will return an object as data
                properties:
                  data:
                    type: object
                    required:
                    - id
                    - type
                    - attributes
                    properties:
                      id:
                        type: string
                      type:
                        type: string
                        default: facility_content
                      attributes:
                        "$ref": "#/components/schemas/FacilityContentSerializer"
                      relationships:
                        "$ref": "#/components/schemas/relationships"
                  meta:
                    "$ref": "#/components/schemas/meta"
        '400':
          description: Some values that were sent couldn't be processed
          content:
            application/json:
              schema:
                type: object
                description: Check the returned info in meta/msg for details
                properties:
                  meta:
                    "$ref": "#/components/schemas/meta"
        '429':
          description: Too many requests
          content:
            application/json:
              schema:
                type: object
                description: Wait for so many seconds as returned in the Retry-After
                  header before accessing this endpoint again
                properties:
                  meta:
                    "$ref": "#/components/schemas/meta"
        '401':
          description: Unauthenticated
          content:
            application/json:
              schema:
                type: object
                description: Requires a valid login
                properties:
                  meta:
                    "$ref": "#/components/schemas/meta"
        '402':
          description: Subscription required
          content:
            application/json:
              schema:
                type: object
                description: This feature requires some extra subscription that is
                  missing
                properties:
                  meta:
                    "$ref": "#/components/schemas/meta"
        '403':
          description: Unauthorized access
          content:
            application/json:
              schema:
                type: object
                description: User is missing the access rights to do this
                properties:
                  meta:
                    "$ref": "#/components/schemas/meta"
wparad commented 8 months ago

Yeah, something does seem broken there. We would of course accept a fix for this so that the appropriate fields and file upload displays correctly.

neongrau commented 8 months ago

Sadly as a ruby dev my TypeScript skills are nonexistent.

wparad commented 8 months ago

Actually I don't think this would be that hard. The first part is the file upload, and there might even be some code laying around in here that does. I do believe file uploads are supported, but that would be the first thing to see, i.e. why aren't they showing up in your case.

The second part is the non-file form data, is there non-file form data that needs to be show? If yes, is it shown? If no, then it should be as easy as copying the code from one of the other sections.

Any effort that is put in, helps a huge amount, even if it isn't a full PR. Because we can pick it up and run with it. If you you feel like this would definitely out of your wheelhouse though, no worries. Someone will try to pick this up in the future when there is capacity available.