How to upload a file in swagger-php array
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Upload Files in Swagger/OpenAPI: Mastering File Handling with JSON Arrays
As a senior developer working with API design, one of the most common points of confusion when defining endpoints via OpenAPI specifications (which Swagger UI visualizes) is handling file uploads. Many developers attempt to send files directly within a standard JSON requestBody, but this approach doesn't align with how HTTP handles binary data.
This post will dive deep into how to correctly structure your API documentation and implementation when dealing with file uploads, addressing the specific challenge of embedding file content (like a resume) within a JSON array using annotations. We will cover both the standard method and the specialized Base64 encoding method you inquired about.
Understanding File Uploads in REST APIs
Before diving into the solution, it’s crucial to understand the fundamental difference between sending data:
- JSON/Text Data: Used for sending structured, human-readable data (names, emails, IDs). This is sent via
application/json. - File Uploads: Files are binary data streams. They cannot be safely embedded directly into a JSON payload. Therefore, file uploads must use the
multipart/form-datacontent type.
When you upload a file using multipart/form-data, the request body is structured differently, allowing the server to parse separate fields for text parameters and the file itself.
Method 1: The Standard Approach (Multipart Form Data)
For true file uploads in RESTful APIs, the industry standard is using multipart/form-data. This method is robust, efficient, and natively supported by all HTTP clients and Swagger UI integrations when configured correctly on the backend framework.
In your OpenAPI annotations, you define the file as a property of type string or file, which signals to Swagger that the client should send data in a multipart format.
Example Annotation Structure (Conceptual):
/**
* @OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Save bulk products",
* @OA\RequestBody(
* required=true,
* description="Bulk product data and resume file",
* @OA\MediaType(
* mediaType="multipart/form-data",
* @OA\Schema(
* type="object",
* @OA\Property(property="products", type="array", @OA\Items(type="object")),
* @OA\Property(property="resumeFile", type="string", format="binary") // Use 'binary' or handle file stream context
* )
* )
* ),
* @OA\Response(response="200", description="Products saved")
* )
*/
While this is the correct architectural approach, it requires your server-side code (e.g., in a Laravel controller) to handle parsing the incoming request stream correctly using methods like request()->file().
Method 2: Embedding File Content via Base64 (Addressing Your Specific Need)
You specifically asked how to send data in an array format and embed the resume as a Base64 string. This method bypasses the complexity of multipart/form-data and keeps the entire payload within a single JSON request body, which is excellent for certain internal microservice communication or when you want everything bundled together.
To achieve this, you must treat the file content as a Base64 encoded string, not a file object. The Swagger annotation describes the resulting structure of the JSON payload.
Refined Annotation Example for Base64 Embedding:
In your annotations, instead of describing a file upload, you describe a field that will contain the encoded string:
/**
* @OA\Post(
* path="/products/save",
* tags={"Product"},
* summary="Save bulk products with embedded resume",
* description="Return bulk products and base64 encoded resume",
* @OA\RequestBody(
* required=true,
* description="Bulk products and Base64 Resume Body",
* @OA\JsonContent(
* type="object",
* @OA\Property(
* property="products",
* type="array",
* @OA\Items(
* type="object",
* @OA\Property(property="first_name", type="string"),
* // ... other product fields
* @OA\Property(property="resume_base64", type="string", description="Base64 encoded resume file content")
* )
* ),
* @OA\Property(
* property="base64_resume",
* type="string",
* format="binary" // Use 'binary' to hint the UI that this is a file-like string
* )
* )
* ),
* )
*/
Implementation Details: How to Handle Base64 in Code
When implementing this endpoint, your backend code must perform two steps: first, read the incoming JSON payload, and second, decode the Base64 string back into binary data.
Conceptual Backend Logic (Laravel/PHP):
use Illuminate\Http\Request;
public function saveProducts(Request $request)
{
// 1. Validate the input structure
$validatedData = $request->validate([
'products' => 'required|array',
'base64_resume' => 'required|string',
]);
$products = $validatedData['products'];
$base64Resume = $validatedData['base64_resume'];
// 2. Decode the Base64 string back into binary data
$resumeData = base64_decode($base64Resume);
// 3. Process the file data (e.g., save to storage)
// $filePath = $this->storeFile($resumeData, 'resumes/');
// ... proceed with saving product data and file ...
return response()->json(['message' => 'Success']);
}
Conclusion
To summarize, while multipart/form-data is the canonical way to handle traditional file uploads in REST APIs, embedding file content directly into a JSON request body using Base64 encoding is a viable and cleaner solution for specific scenarios where you want to keep all data transmission within a single JSON transaction.
When documenting these endpoints with Swagger annotations, focus on describing the final structure of the JSON payload you expect to receive or send (as shown in Method 2). Remember that the complexity of file handling is often shifted from the API layer into the application logic layer where the actual encoding/decoding takes place. For robust applications, always ensure your documentation aligns with the most secure and standard practices, similar to how modern frameworks like those used by laravelcompany.com enforce clean separation between data and binary streams.