Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.prism.byescaleira.com/llms.txt

Use this file to discover all available pages before exploring further.

Multipart Forms

When browsers submit forms with file inputs, they encode the data as multipart/form-data — a format that bundles multiple fields (text and binary) into a single HTTP body. Prism parses this format natively, giving you typed access to each part.

How Multipart Works

A multipart request body is split by a boundary string into parts. Each part has headers (name, filename, content type) and a body. Prism handles the boundary parsing and gives you a clean array of parts.
Basic Multipart Parsing
await server.post("/submit") { request in
    let parts = try request.multipartParts()

    for part in parts {
        print("Field: \(part.name)")
        if let filename = part.filename {
            print("  File: \(filename), size: \(part.data.count) bytes")
            print("  Type: \(part.contentType ?? "unknown")")
        } else {
            print("  Value: \(part.stringValue ?? "")")
        }
    }

    return .json(["received": parts.count])
}

Text Fields vs File Parts

The key difference: file parts have a filename, text fields don’t.
Separating Fields and Files
await server.post("/profile") { request in
    let parts = try request.multipartParts()

    var fields: [String: String] = [:]
    var files: [String: Data] = [:]

    for part in parts {
        if let filename = part.filename {
            files[filename] = part.data
        } else {
            fields[part.name] = part.stringValue ?? ""
        }
    }

    let name = fields["name"] ?? "Unknown"
    let bio = fields["bio"] ?? ""

    return .json(["name": name, "bio": bio, "filesUploaded": files.count])
}

Contact Form Example

Contact Form with Attachment
await server.post("/contact") { request in
    let parts = try request.multipartParts()

    var email = ""
    var message = ""
    var attachment: Data?

    for part in parts {
        switch part.name {
        case "email":
            email = part.stringValue ?? ""
        case "message":
            message = part.stringValue ?? ""
        case "attachment":
            if part.filename != nil {
                attachment = part.data
            }
        default:
            break
        }
    }

    guard !email.isEmpty, !message.isEmpty else {
        return .json(["error": "Email and message required"], status: .badRequest)
    }

    // Process the contact form...
    return .json(["status": "received"])
}

HTML Form

Browser Form
<form action="/contact" method="POST" enctype="multipart/form-data">
    <input type="email" name="email" required>
    <textarea name="message" required></textarea>
    <input type="file" name="attachment">
    <button type="submit">Send</button>
</form>
For structured file upload handling with size limits and type validation, see File Uploads — it builds on top of multipart parsing with PrismUploadProcessor.
Each multipart part’s data property contains the raw bytes. For text fields, use stringValue which decodes the data as UTF-8. For files, work with data directly or use the upload processor.