6

I'm working with a Magento 2 project that need to upload image using a POST endpoint

How can I send image content to this endpoint?

Or I have to base64 the image at client side and send the base64 content to POST endpoint?

Thank you very much.

9

If you want to upload product image using rest api. You need to pass below parameters in your request.

Your media upload url - http://127.0.0.1/megento2/index.php/rest/V1/products/{sku}/media.

Method name - Post

Below are the body parameters :

[
  {
    "id": 0,
    "media_type": "test",
    "label": "test",
    "position": 0,
    "disabled": true,
    "types": [
      "thumbnail"
    ],
    "file": "test.png",
    "content": {
      "base64_encoded_data": "Here i have passed base64_encoded data of image",
      "type": "file/png",
      "name": "test.png"
    },
    }
  }
]

Note : Make sure you pass base64_encoded_data of image.

  • Hi Manthan Dave, so basically Magento 2 API does not support file input, right? I worked with Laravel API, and they support file input, wonder why Magento 2 doesn't do this? – Hoang Trinh Jun 23 '17 at 9:56
  • 1
    Yes Bang on @piavgh - Magento 2 rest api for media upload its not supporting file input , you must need to pass base64 encoded image. or you can create your custom observer for that . – Manthan Dave Jun 23 '17 at 10:19
  • Thank you Manthan. Can you please tell me more about the custom observer approach? I didn't understand it clearly. I think that whether we use observer or not, we still have to get the file from api, right? But this is what Magento 2 API doesn't support. – Hoang Trinh Jun 23 '17 at 15:46
  • Well better to do one thing , send base64_encoded image and decode it where you needed file format. using base64_decode and then do put_file_contents with image name it will create new image for you – Manthan Dave Jun 23 '17 at 16:14
0

To upload image you can use jquery fileupload. Here is example

view/frontend/layout/default.xml (layout you need)

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css media="all" src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
    </head>
</page>

You could create widget or just use require js

$wrapper.find('input[type=file]').fileupload({
    dataType: 'json',
    formData: {
       'form_key': window.FORM_KEY
    },
    limitMultiFileUploads: 1,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    done: function (e, data) {
    }
});

More information here https://github.com/blueimp/jQuery-File-Upload

and your Controller

<?php
namespace Vendor\Module\Controller;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\UrlInterface;

class Upload extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    protected $resultJsonFactory;

    /**
     * @var \Magento\MediaStorage\Model\File\UploaderFactory
     */
    protected $uploaderFactory;

    /**
     * @var \Magento\Framework\Filesystem\Directory\Write
     */
    protected $mediaDirectoryWrite;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     * @param \Magento\Framework\Filesystem $filesystem
     * @param \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
    ) {
        parent::__construct($context);

        $this->resultJsonFactory = $resultJsonFactory;
        $this->uploaderFactory = $uploaderFactory;
        $this->mediaDirectoryWrite = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
    }

    /**
     * @return \Magento\Framework\Controller\Result\JsonFactory
     */
    public function execute()
    {
        if (!$this->mediaDirectoryWrite->isWritable('MEDIA_PATH')) {
            $this->mediaDirectoryWrite->create('MEDIA_PATH');
        }

        $resultJson = $this->resultJsonFactory->create();
        try {
            $targetPath = $this->mediaDirectoryWrite->getAbsolutePath('MEDIA_PATH');
            $uploader = $this->uploaderFactory->create([
                'fileId' => 'file'
            ]);
            $uploader->setAllowedExtensions(['gif', 'png', 'jpg', 'jpeg']);
            $uploader->setAllowRenameFiles(true);
            $uploader->setFilesDispersion(true);
            $result = $uploader->save($targetPath);

            $result['file'] = ltrim($result['file'], '/');
            $result['url'] = $this->_url->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA])
                . 'MEDIA_PATH'
                . '/'
                . $result['file'];
        } catch (\Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }

        return $resultJson->setData($result);
    }
}
  • Thank Nicholas. But I need to send image to REST API, not controller as you suggested. – Hoang Trinh Jun 22 '17 at 2:56
  • Look at devdocs.magento.com/swagger/index_20.html how POST was implemented in catalogProductRepositoryV1 method. In this way you should send base64encoded data. – Nicholas Miller Jun 22 '17 at 3:10
  • You mean this part "content": { "base64EncodedData": "string", "type": "string", "name": "string" }, right? – Hoang Trinh Jun 22 '17 at 3:12
  • yes, in mediaGalleryEntries – Nicholas Miller Jun 22 '17 at 3:13
  • I strongly disagree with your statement. Using a custom controller instead of the provided API is not recommendable. Why would any webserver disallow a JSON post but allow a file upload? – ooxi Jun 25 '17 at 19:25
0

By default it is necessary to send the image encoded in base 64.

For a project, a client asked me to prevent the images from being sent encoded through the API to reduce the transmission time when the products of the catalog were updated. As it is obviously not possible to send the image files through the API the solution was a plugin that modifies the behavior of magento 2 to search the image files in the folder "pub/media/import"

https://github.com/olivertar/m2_api_product_images

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.