8

I'm trying to create an api route with input parameters but I'm not getting the expected result.

Here is my webapi.xml:

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
    <route url="/V1/foo" method="POST" secure="true">
        <service class="..\FooInterface"
                 method="getFooById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
        <data>
            <parameter name="id" force="true">%id%</parameter>
        </data>
    </route>
</routes>

Here my interface:

interface FooInterface
{
    /**
     * Test function
     *
     * @api
     * @param string $id
     * @return string
     */
    public function getFooById($id);
}

And here the class:

class Foo implements FooInterface
{
    /**
     * {@inheritdoc}
     */
    public function getFooById($id){
        return $id;
    }
}

I'm omitting the di.xml with the preference. Now if I call that route whatever I do all I get back is %id%. Even if I don't put any parameter I get that instead of an error or something.

What am I doing wrong here?

Here is the call in postman: enter image description here enter image description here

I tried:

  • sending a get request
  • sending a get request with parameter /order?id=foo
  • sending a post request
  • sending a post request with form-data
  • sending a post request with raw data (as seen in screenshot)

All have the same result -> %id%

I'm using community edition btw.

2
  • Have you find any solution for his issue? Please let me know I am facing same issue thanks Commented May 11, 2019 at 6:37
  • Sorry left the company and can't access the code anymore. I think I did what I started in my last comment in the only answer.
    – steros
    Commented May 11, 2019 at 6:41

1 Answer 1

4

After check the core modules, found that parameter node in webapi.xml is only used in Customer Module for self resource type.

Below file is responsible for Convert parameter placeholder with value.

/**
 * Replaces a "%customer_id%" value with the real customer id
 */
Magento\Webapi\Controller\Rest\ParamOverriderCustomerId 

Now there are two ways to pass parameter in API.

Solution 1:

webapi.xml like below:

<?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/foo" method="POST" secure="true">
        <service class="..\FooInterface" method="getFooById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

and specify $id argument in Interface class and in implementation definition also. In this case, you need to pass id as body content.

Solution 2:

webapi.xml like below:

<?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/foo:id" method="POST" secure="true">
        <service class="..\FooInterface" method="getFooById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

and specify $id argument in Interface class and in implementation definition also. In this case, you need to pass id in URL as argument. For this you can check product module also.

10
  • Yeah that's exactly what I want, to make it required!
    – steros
    Commented Jul 24, 2017 at 11:00
  • Why downvote.. not getting. As you declared Inerface with Argument. Argument is required already. If you will not add in webapi.xml. It will work, I tried this and it worked fine Commented Jul 24, 2017 at 11:27
  • Maybe it is not clear? I specifically want to use the data element in the webapi.xml. Just leaving it out gives the expected output but does not solve the actual problem.
    – steros
    Commented Jul 24, 2017 at 11:41
  • Ah you led me to something: "* Parameters in the webapi.xml can be forced. This ensures that on specific routes, a specific value is always used. * For instance, if there is a ".../me/..." route, the route should use only user information specific to the * currently logged in user. More specifically, if there was a "/customers/me/addresses" route, the service method * invoked could have a signature of "getAddresses($customerId)", but in the webapi.xml, the $customerId parameter * would be forced to be the customer id of the current authenticated user."
    – steros
    Commented Jul 25, 2017 at 14:07
  • Found in ParamOverriderInterface.php - I'm sick at the moment and have trouble grasping things but if I get it right at this state. Those data and parameter elements have not much to do with the request parameter. Instead they force a value for a parameter (wherever that comes from).
    – steros
    Commented Jul 25, 2017 at 14:10

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.