openapi-to-graphql icon indicating copy to clipboard operation
openapi-to-graphql copied to clipboard

non-null array items in graphql schema

Open zebapy opened this issue 3 years ago • 0 comments

We have an openapi spec endpoint that produces a gql query like this

type Query {
  """
  Equivalent to GET /datasets
  """
  datasets: [Dataset]
}

part of spec

   /datasets:
    get:
      responses:
        200:
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Dataset"
          description: A list of datasets
        400:
          $ref: "#/components/responses/BadRequest"
        401:
          $ref: "#/components/responses/Unauthorized"
        403:
          $ref: "#/components/responses/Forbidden"
        404:
          $ref: "#/components/responses/NotFound"
        500:
          $ref: "#/components/responses/InternalServerError"
      description: Get a list of the datasets available in the developer’s account
      operationId: getDatasets
      summary: List datasets
      tags:
        - datasets

dataset schema

    Dataset:
      type: object
      required:
        - created_at
        - id
        - identity_sets
        - output_to_streams
        - resource_type
        - updated_at
        - upload_directory
      properties:
        created_at:
          type: string
          description: When this resource was created.
          format: date-time
        id:
          type: string
          description: A unique ID for this resource.
          example: 8cd2dcf6-f2b3-4318-b8b3-eb19ab18d29d
          format: uuid
        identity_sets:
          allOf:
            - $ref: "#/components/schemas/IdentitySets"
            - type: object
              description: ""
        incremental_column:
          type: string
          description: ""
          example: updated_at
        output_to_streams:
          allOf:
            - $ref: "#/components/schemas/OutputToStreams"
            - type: object
              description: ""
        resource_type:
          type: string
          description: The type of this resource.
          example: datasets
        updated_at:
          type: string
          description: When this resource was last updated.
          format: date-time
        upload_directory:
          type: string
          description: ""
          example: abc_orders
          pattern: "^[A-Za-z0-9_][-A-Za-z0-9_ ]*$"
        upsert_columns:
          type: array
          items:
            type: string
          description: ""
          example:
            - id
      additionalProperties: false
      description: "Tabular data describing orders, customers, leads, etc."

But we never send back [null] arrays when fetching this data.

How can we ensure the schema generates as datasets: [Dataset!] instead? Either the object is in the array or it is an empty array.

My understanding is unless our spec explicitly says "this object can be null", then perhaps this is a bug?

A workaround for this is transforming the schema with graphql-tools https://www.graphql-tools.com/docs/schema-wrapping#modifying

const schema = wrapSchema({
    schema: originalSchema,
    transforms: [
      // convert all lists from [MyType] to [MyType!]
      new TransformRootFields((_operationName, _fieldName, fieldConfig) => {
        if (fieldConfig.type instanceof GraphQLList) {
          const item = fieldConfig.type.ofType;

          // if it's already nonnull, skip changing it
          if (item instanceof GraphQLNonNull) return fieldConfig;

          fieldConfig.type = new GraphQLList(new GraphQLNonNull(item));
        }

        return fieldConfig;
      }),
    ],
  });

zebapy avatar May 17 '22 15:05 zebapy