AshOaskit.MultipartSupport (AshOasKit v0.2.1)

View Source

Generates OpenAPI schemas for file upload and multipart/form-data requests.

This module handles the detection and schema generation for actions that accept file uploads, generating appropriate multipart/form-data request body schemas.

File Upload Detection

An action is considered to support file uploads if any of its arguments have a type of Ash.Type.File or if the action is explicitly marked for file upload.

Generated Schema Structure

For actions with file arguments, the request body includes both application/vnd.api+json and multipart/form-data content types:

%{
  requestBody: %{
    content: %{
      "application/vnd.api+json" => %{
        schema: json_schema
      },
      "multipart/form-data" => %{
        schema: multipart_schema
      }
    }
  }
}

Multipart Schema Format

The multipart schema uses standard OpenAPI binary format:

%{
  type: :object,
  properties: %{
    file: %{
      type: :string,
      format: :binary,
      description: "The file to upload"
    },
    data: %{
      type: :object,
      description: "JSON:API resource data"
    }
  }
}

Usage

# Check if an action supports file uploads
MultipartSupport.has_file_upload?(action)

# Build multipart request body schema
request_body = MultipartSupport.build_request_body(action, resource, opts)

# Build just the multipart content schema
schema = MultipartSupport.build_multipart_schema(action, opts)

Summary

Functions

Builds encoding hints for multipart fields.

Builds a complete multipart content specification with encoding.

Builds the multipart/form-data schema for an action.

Builds a complete request body schema with multipart support.

Gets the file arguments from an action.

Checks if an action has any file upload arguments.

Functions

build_encoding(action)

@spec build_encoding(map() | struct()) :: map()

Builds encoding hints for multipart fields.

OpenAPI 3.0+ supports encoding objects that specify how each field should be serialized in multipart requests.

Parameters

  • action - The Ash action struct

Returns

A map of field names to encoding specifications.

Examples

iex> MultipartSupport.build_encoding(upload_action)
%{
  "avatar" => %{contentType: "application/octet-stream"},
  "data" => %{contentType: "application/json"}
}

build_multipart_content(action, opts)

@spec build_multipart_content(
  map() | struct(),
  keyword()
) :: map()

Builds a complete multipart content specification with encoding.

Returns a content object suitable for direct inclusion in a request body's content map.

Parameters

  • action - The Ash action struct
  • opts - Options keyword list

Returns

A map with schema and encoding for multipart/form-data.

Examples

iex> MultipartSupport.build_multipart_content(upload_action, [])
%{
  schema: %{...},
  encoding: %{...}
}

build_multipart_schema(action, _)

@spec build_multipart_schema(
  map() | struct(),
  keyword()
) :: map()

Builds the multipart/form-data schema for an action.

Creates an OpenAPI schema that describes the multipart form structure, including file fields and JSON data fields.

Parameters

  • action - The Ash action struct
  • opts - Options keyword list

Returns

A map representing the OpenAPI schema for multipart encoding.

Examples

iex> MultipartSupport.build_multipart_schema(upload_action, [])
%{
  type: :object,
  properties: %{
    file: %{type: :string, format: :binary},
    data: %{type: :object}
  }
}

build_request_body(action, resource, opts)

@spec build_request_body(map() | struct(), module(), keyword()) :: map()

Builds a complete request body schema with multipart support.

If the action has file arguments, generates a request body that supports both JSON:API and multipart/form-data content types.

Parameters

  • action - The Ash action struct
  • resource - The Ash resource module
  • opts - Options keyword list
    • :version - OpenAPI version ("3.0" or "3.1")

Returns

A map representing the OpenAPI request body object.

Examples

iex> MultipartSupport.build_request_body(upload_action, MyApp.User, [])
%{
  required: true,
  content: %{
    "application/vnd.api+json" => %{...},
    "multipart/form-data" => %{...}
  }
}

file_arguments(action)

@spec file_arguments(map() | struct()) :: [map()]

Gets the file arguments from an action.

Returns a list of arguments that have file types.

Parameters

  • action - The Ash action struct

Returns

List of argument structs with file types.

Examples

MultipartSupport.file_arguments(upload_action)
# => [%{name: :avatar, type: Ash.Type.File, ...}]

has_file_upload?(action)

@spec has_file_upload?(map() | struct()) :: boolean()

Checks if an action has any file upload arguments.

Returns true if the action has any argument of type Ash.Type.File or any embedded type containing a file.

Parameters

  • action - The Ash action struct

Returns

Boolean indicating if the action accepts file uploads.

Examples

iex> MultipartSupport.has_file_upload?(upload_action)
true

iex> MultipartSupport.has_file_upload?(simple_create_action)
false