Question

I have a very weird problem when trying to extend Magento2 API, I followed all the right steps, however im getting this syntax error when calling http://appfactory.loc/index.php/rest/V1/appfactory/categories , although im pretty sure it's not a syntax thing, i rechecked the syntax for each file several times.

{
  "messages": {
    "error": [
      {
        "code": 500,
        "message": "Fatal Error: 'syntax error, unexpected 'interface' (T_INTERFACE)' in 'C:\\stage\\appfactory-magento2\\app\\code\\AppFactory\\Basic\\Api\\CategoryInterface.php' on line 5",
        "trace": "Trace is not available."
      }
    ]
  }
}

My structure is as follows:

AppFactory/Basic/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/appfactory/categories" method="GET">
        <service class="AppFactory\Basic\Api\CategoryInterface" method="getList"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>

    <route url="/V1/appfactory/categories/:id" method="GET">
        <service class="AppFactory\Basic\Api\CategoryInterface" method="getById"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>

</routes>

AppFactory/Basic/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="AppFactory\Basic\Api\CategoryInterface"
                type="AppFactory\Basic\Model\Api\Category" />
</config>

AppFactory/Basic/Model/Api/Category.php

namespace AppFactory\Basic\Model\Api;
use AppFactory\Basic\Api\CategoryInterface;
 
class Category implements CategoryInterface{


    /**
     * Return all the filterable attributes for this category
     *
     * @return array
     */
    public function getById( $id ){return "Test"; }
public function getList() {return "Test2";}
}

AppFactory/Basic/Api/CategoryInterface.php

<?php

namespace AppFactory\Basic\Api;
 
interface CategoryInterface
{

    public function getById( $id );
    public function getList();
}
Was it helpful?

Solution

You need doc blocks for your Interface.

You should use a repository interface which return entities. And this have to be defined by your method doc blocks...

/**
 * @api
 */
namespace AppFactory\Basic\Api;

interface CategoryRepositoryInterface {

    /**
     * @return \AppFactory\Basic\Api\CategoryInterface[]
     */
    public function getList();

    ...
}

This annotations will be parsed by Magento in order to fulfill the API request.

UPDATE 1:

I've reproduce your setup in a CE-2.2-dev Magento instance and got this error message:

{
  "message": "Each getter must have description with @return annotation. See AppFactory\\Basic\\Api\\CategoryInterface::getById()",
  "trace": "#0 /Volumes/Dev-Part/Workspace/Hackathon/m2-develop/lib/internal/Magento/Framework/Reflection/MethodsMap.php(169): Magento\\Framework\\Reflection\\TypeProcessor->getGetterReturnType(Object(Zend\\Code\\Reflection\\MethodReflection))\n#1 /Volumes/Dev-Part/Workspace/Hackathon/m2
  ...
}

After changing the interface to the following it does work

<?php

namespace AppFactory\Basic\Api;

/**
 * @api
 */
interface CategoryInterface
{
    /**
     * @param $id
     * @return string
     */
    public function getById( $id );

    /**
     * @return array
     */
    public function getList();
}

What I mean before is that you should use the "Repository" pattern in order to run close to Magento 2 standards...

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top