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" => "user@example.com",
        "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.

  • try it as (string)json_encode($customerData) – Aman Alam Jan 15 at 6:56
  • thax #Aman, but its not working. – Atul Jan 15 at 7:01
  • where is your data processing interface? – Aman Alam Jan 15 at 7:10
  • I didn't create it, is it necessary ? – Atul Jan 15 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 Jan 15 at 7:13
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);
  • 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 Jan 15 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 Jan 15 at 8:05
  • I am getting this error now - [message] => Class array does not exist – Atul Jan 15 at 8:13
  • Change public function createUpdate(array $data); to public function createUpdate($data); at Namespace\Modulename\Api\ManageCustomerInterface – Amit Bera Jan 15 at 8:15
  • did the same, but still giving same error - [message] => Class array does not exist – Atul Jan 15 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");
0

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" => "user@example.com",
            "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));

Here is your test live test url: http://magento.amanweb.in/test.php

  • 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 Jan 16 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 Jan 16 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 Jan 16 at 7:14
  • just var_dump($data) instead of decoding json – Aman Alam Jan 16 at 7:45
  • Can you please share zip file of your module, via ur site url – Atul Jan 16 at 8:05

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.