1

I have created custom API that excepting 'mixed' type parameter and returning the 'string' as I defined. In interface I define parameter type 'mixed'. As I am trying to pass array as json_encode, it giving me Warning: json_decode() expects parameter 1 to be string, array given in error.` Please let me know how can I pass json array as parameter and return the same.

Here is my code -
etc/webapi.xml

<?xml version="1.0" ?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route method="POST" url="/V1/managecustomers">
        <service class="Namespace\Modulename\Api\ManageCustomerInterface" method="createUpdate"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

etc/di.xml -

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Namespace\Modulename\Api\ManageCustomerInterface" type="Namespace\Modulename\Model\Managecustomer"/>
</config>

Namespace\Modulename\Api\ManageCustomerInterface.php :-

namespace Namespace\Modulename\Api;

interface ManageCustomerInterface
{
    /**
     * 
     * @param mixed $data
     * @return string
     */
    public function createUpdate($data);
}

Namespace\Modulename\Model\Managecustomer.php - :

namespace Namespace\Modulename\Model;

use Namespace\Modulename\Api\ManageCustomerInterface;

class Managecustomer implements ManageCustomerInterface
{
    /**
     * 
     * @param mixed $data
     * @return string
     */
    public function createUpdate($data) {
        $data = json_decode($data);
        //echo "<pre>"; print_r($data); die;
        return "Hello";

    }
}

If i am passing 'data' parameter as string like - $customerData = [ 'data' => "Abcd" ];

Then its running fine. But If i am trying to pass 'data' as array like-

$customerData = [
    'data' => [
        "email" => "[email protected]",
        "firstname" => "John",
        "lastname" => "Doe",
        "storeId" => 1,
        "websiteId" => 1,
        "address"=>[
            "street" => "phase-1",
            "phone_no"=> "321654213"
        ]
    ]
];

Then its giving error - Warning: json_decode() expects parameter 1 to be string, array given in error.`

Here is my testapi.php file code -

$ch = curl_init("http://localhost/mage23/index.php/rest/all/V1/managecustomers");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($customerData));
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));

$result = curl_exec($ch);

echo '<pre>';print_r($result);

Please let me know how can I pass array as parameter in API.

12
  • try it as (string)json_encode($customerData)
    – Aman Alam
    Commented Jan 15, 2019 at 6:56
  • thax #Aman, but its not working.
    – Atul
    Commented Jan 15, 2019 at 7:01
  • where is your data processing interface?
    – Aman Alam
    Commented Jan 15, 2019 at 7:10
  • I didn't create it, is it necessary ?
    – Atul
    Commented Jan 15, 2019 at 7:11
  • I think so you must need a getter and setter for your data so that your json data get passed in process
    – Aman Alam
    Commented Jan 15, 2019 at 7:13

4 Answers 4

1

If you've added proper docblock and still getting this error, replace @param mixed to @param string[] or @param mixed[] as according to magento devdocs.

Valid scalar types include: mixed (or anyType), bool (or boolean), str (or string), integer (or int), float, and double.

Also note that you must always use fully qualified class name or a fully qualified interface name in docblock.

Reference :

https://devdocs.magento.com/guides/v2.2/extension-dev-guide/service-contracts/service-to-web-service.html

0

You have to change to return paramters type of Namespace\Modulename\Model\Managecustomer::createUpdate() is wrong.

 /**
     * 
     *  @param array $data
     * @return string
     */

    public function createUpdate( array $data) {
    // donot need json_decode
        //$data = json_decode($data);
        //echo "<pre>"; print_r($data); die;
        return "Hello";

    }

Also, at Namespace\Modulename\Api\ManageCustomerInterface, DO NOT use PHP7 scalar argument types or return types as you want to hook this into the REST API!.

So:

   /**
     * 
    * @param \Magento\Customer\Api\Data\CustomerInterface[] $data
   * @return string
   */

public function createUpdate(array $data);
5
  • why I need this @param \Magento\Customer\Api\Data\CustomerInterface[] $data, And I applied json_decode just because i want to use that passed data here. and Is 'array' "@param array $data" type allowed?
    – Atul
    Commented Jan 15, 2019 at 8:03
  • Because of array is PHP7 scalar argument type and if you will use this then you we will get error.
    – Amit Bera
    Commented Jan 15, 2019 at 8:05
  • I am getting this error now - [message] => Class array does not exist
    – Atul
    Commented Jan 15, 2019 at 8:13
  • Change public function createUpdate(array $data); to public function createUpdate($data); at Namespace\Modulename\Api\ManageCustomerInterface
    – Amit Bera
    Commented Jan 15, 2019 at 8:15
  • did the same, but still giving same error - [message] => Class array does not exist
    – Atul
    Commented Jan 15, 2019 at 8:35
0

Namespace\Modulename\Api\ManageCustomerInterface.php :-

namespace Namespace\Modulename\Api;

interface ManageCustomerInterface
{
    /**
     * 
     * @param string $data
     * @return string
     */
    public function createUpdate($data);
}

Namespace\Modulename\Model\Managecustomer.php - :

namespace Namespace\Modulename\Model;

use Namespace\Modulename\Api\ManageCustomerInterface;

class Managecustomer implements ManageCustomerInterface
{
    /**
     * 
     * @param string $data
     * @return string
     */
    public function createUpdate($data) {
        $data = json_decode($data,TRUE);
        echo "<pre>"; print_r($data); 
        die;
    }
}

in testapi.php file code use :-

$ch = curl_init("http://localhost/mage23/index.php/rest/V1/managecustomers");
or
$ch = curl_init("http://localhost/mage23/rest/V1/managecustomers");
-1

Here is the working and tested version of your problem

For running API recieve POST data your must need below mentioned files and methods.

Here is the list of files needed.

Note: Replace Amanweb with your module vendor and Testapi with your module name.

Amanweb\Testapi\Api\TestapiRepositoryInterface.php

<?php
namespace Amanweb\Testapi\Api;

interface TestapiRepositoryInterface
{
    /**
     * create update customer
     * @api
     * @param mixed $param
     * @return array
     */
    public function createUpdate($param);
}

Amanweb\Testapi\etc\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Amanweb\Testapi\Api\TestapiRepositoryInterface" type="Amanweb\Testapi\Model\TestapiRepository" />
</config>

Amanweb\Testapi\etc\webapi.xml

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/managecustomers" method="POST">
        <service class="Amanweb\Testapi\Api\TestapiRepositoryInterface" method="createUpdate"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

Amanweb\Testapi\Model\TestapiRepository.php

<?php
namespace Amanweb\Testapi\Model;

use Amanweb\Testapi\Api\TestapiRepositoryInterface;

class TestapiRepository implements TestapiRepositoryInterface
{
    /**
     * {@inheritdoc}
     */
    public function createUpdate($param)
    {
        return json_encode($param);
    }
}

testapi.php

<?php
$ch = curl_init("http://magento.amanweb.in/rest/V1/managecustomers");
$customerData = [
    "param" => [
            "email" => "[email protected]",
            "firstname" => "John",
            "lastname" => "Doe",
            "storeId" => 1,
            "websiteId" => 1,
            "address"=>[
                "street" => "phase-1",
                "phone_no"=> "321654213"
            ]
        ]
];
echo json_encode($customerData);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($customerData));
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$result = curl_exec($ch);
echo '<pre>';
print_r(json_decode($result));
7
  • Thx #Aman its working fine, but two things, 1 - its giving error on 'Swagger' (Failed to load API definition. ) and 2- In model function if I am trying to print passed parameter like 'echo "<pre>"; var_dump($param); die;' , its returning 'NULL'. Can you please check at your end also, how can I access passed parameter in Model function ?
    – Atul
    Commented Jan 16, 2019 at 6:51
  • where you getting this error on 'Swagger' (Failed to load API definition. ) . Regarding var dump i have tested print_r and its worked.
    – Aman Alam
    Commented Jan 16, 2019 at 7:06
  • Here is mine model function with print statement - public function createUpdate($data) { //$data = json_decode($data,TRUE); echo "<pre>"; var_dump($data); die; return json_encode($data); } And on 'Swagger' on landing page. Can you please share link to download your module ? FYI i am working on Mage2.3
    – Atul
    Commented Jan 16, 2019 at 7:14
  • just var_dump($data) instead of decoding json
    – Aman Alam
    Commented Jan 16, 2019 at 7:45
  • Can you please share zip file of your module, via ur site url
    – Atul
    Commented Jan 16, 2019 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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