# Handling File Upload As common a problem as it may seem, handling file upload requires a custom implementation in your app. This page will guide you in handling file upload in your API, with the help of [VichUploaderBundle](https://github.com/dustin10/VichUploaderBundle). It is recommended you [read the documentation of VichUploaderBundle](https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/index.md) before proceeding. It will help you get a grasp on how the bundle works, and why we use it. ## Installing VichUploaderBundle Install the bundle with the help of composer: ```bash docker-compose exec php composer require vich/uploader-bundle ``` This will create a new configuration file that you will need to slightly change to make it look like this. ```yaml # config/packages/vich_uploader.yaml vich_uploader: db_driver: orm mappings: media_object: uri_prefix: /media upload_destination: '%kernel.project_dir%/public/media' ``` ## Configuring the Entity Receiving the Uploaded File In our exemple, we will create a `MediaObject` API resource. We will post files to this resource endpoint, and then link the newly created resource to another resource (in our case: Book). The `MediaObject` resource is implemented like this: ```php validator = $validator; $this->doctrine = $doctrine; $this->factory = $factory; } /** * @IsGranted("ROLE_USER") */ public function __invoke(Request $request): MediaObject { $mediaObject = new MediaObject(); $form = $this->factory->create(MediaObjectType::class, $mediaObject); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->doctrine->getManager(); $em->persist($mediaObject); $em->flush(); // Prevent the serialization of the file property $mediaObject->file = null; return $mediaObject; } // This will be handled by API Platform and returns a validation error. throw new ValidationException($this->validator->validate($mediaObject)); } } ``` As you can see, the action uses a form. You will need this form to be like this: ```php add('file', FileType::class, [ 'label' => 'label.file', 'required' => false, ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => MediaObject::class, 'csrf_protection' => false, ]); } public function getBlockPrefix() { return ''; } } ``` ## Making a Request to the `/media_objects` Endpoint Your `/media_objects` endpoint is now ready to receive a `POST` request with a file. This endpoint accepts standard `multipart/form-data` encoded data, but not JSON data. You will need to format your request accordingly. After posting your data, you will get a response looking like this: ```json { "@type": "http://schema.org/ImageObject", "@id": "/media_objects/", "contentUrl": "", } ``` ## Linking a MediaObject Resource to Another Resource We now need to update our `Book` resource, so that we can link a `MediaObject` to serve as the book cover. We first need to edit our Book resource, and add a new property called `image`. ```php " } ``` Voila! You can now send files to your API, and link them to any other resources in your app.