0

I know that Magento has CLI for creating new users, but I need to do that via API rest. And extending all CRUD functionalities.

So I tried to create a new module for do that, but it's not working:

These are the 2 main files:

Api/UsersRepositoryInterface.php

namespace Gsp\Users\Api;

interface UserRepositoryInterface
{
    /**
     * Retrieve User entity by ID
     * @param int $id
     * @return \Magento\User\Model\User
     */
    public function getById($id);

    /**
     * Save User
     * @param \Magento\User\Model\User
     * @return \Magento\User\Model\User
     */
    public function save(\Magento\User\Model\User $user);
}

Model/UsersRepository.php

namespace Gsp\Users\Model;

class UserRepository implements \Gsp\Users\Api\UserRepositoryInterface
{
    /**
     * User model factory
     *
     * @var \Magento\User\Model\UserFactory
     */
    protected $userFactory;

    public function __construct(
        \Magento\User\Model\UserFactory $userFactory
    )
    {
        $this->userFactory = $userFactory;
    }

    /**
     * Retrieve User entity by ID
     * @param int $id
     * @return \Magento\User\Model\User
     */
    public function getById($id)
    {
        return $this->userFactory->create()->load($id);
    }


    /**
     * Save User
     * @param \Magento\User\Model\User
     * @return \Magento\User\Model\User
     */
    public function save(\Magento\User\Model\User $user)
    {
        die('ok');
    }

}

When I call the getById method it shows that error:

{
    "message": "Getter return type must be specified using @return annotation. See Magento\\User\\Model\\User::getFirstName()",
    "trace": "#0 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/Reflection/MethodsMap.php(163): Magento\\Framework\\Reflection\\TypeProcessor->getGetterReturnType(Object(Zend\\Code\\Reflection\\MethodReflection))\n#1 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/Reflection/MethodsMap.php(100): Magento\\Framework\\Reflection\\MethodsMap->getMethodMapViaReflection('\\\\Magento\\\\User\\\\M...')\n#2 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/Reflection/DataObjectProcessor.php(77): Magento\\Framework\\Reflection\\MethodsMap->getMethodsMap('\\\\Magento\\\\User\\\\M...')\n#3 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/Webapi/ServiceOutputProcessor.php(107): Magento\\Framework\\Reflection\\DataObjectProcessor->buildOutputDataArray(Object(Magento\\User\\Model\\User\\Interceptor), '\\\\Magento\\\\User\\\\M...')\n#4 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/Webapi/ServiceOutputProcessor.php(59): Magento\\Framework\\Webapi\\ServiceOutputProcessor->convertValue(Object(Magento\\User\\Model\\User\\Interceptor), '\\\\Magento\\\\User\\\\M...')\n#5 /opt/bitnami/apps/magento/htdocs/vendor/magento/module-webapi/Controller/Rest.php(308): Magento\\Framework\\Webapi\\ServiceOutputProcessor->process(Object(Magento\\User\\Model\\User\\Interceptor), 'Gsp\\\\Users\\\\Api\\\\U...', 'getById')\n#6 /opt/bitnami/apps/magento/htdocs/vendor/magento/module-webapi/Controller/Rest.php(216): Magento\\Webapi\\Controller\\Rest->processApiRequest()\n#7 /opt/bitnami/apps/magento/htdocs/var/generation/Magento/Webapi/Controller/Rest/Interceptor.php(37): Magento\\Webapi\\Controller\\Rest->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#8 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/App/Http.php(135): Magento\\Webapi\\Controller\\Rest\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#9 /opt/bitnami/apps/magento/htdocs/vendor/magento/framework/App/Bootstrap.php(258): Magento\\Framework\\App\\Http->launch()\n#10 /opt/bitnami/apps/magento/htdocs/index.php(39): Magento\\Framework\\App\\Bootstrap->run(Object(Magento\\Framework\\App\\Http))\n#11 {main}"
}

I don't what it means. But using var_dump(get_class($this->userFactory->create()->load($id))); I figured out it's not the same class?

It showed me that: "Magento\User\Model\User\Interceptor"

So I'm not retrieving the right class? Why Interceptor?

1

First Interceptor class is the class autogenerated in order to make the Magento plugin works. (Documentation : http://devdocs.magento.com/guides/v2.1/extension-dev-guide/plugins.html)

Then you need to use interface class in the return type because you do not know the final class implementation due to injection dependency.

So have a look in the native Magento web api interface :

vendor/magento/module-customer/Api/CustomerRepositoryInterface.php:47

/**
 * Get customer by customer ID.
 *
 * @param int $customerId
 * @return \Magento\Customer\Api\Data\CustomerInterface
 * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with the specified ID does not exist.
 * @throws \Magento\Framework\Exception\LocalizedException
 */
public function getById($customerId);

So try to use this return type.

Then check the Magento 2 implementation of this function, it uses repository in order to retrieve the customer :

vendor/magento/module-customer/Model/ResourceModel/CustomerRepository.php:244

/**
 * {@inheritdoc}
 */
public function getById($customerId)
{
    $customerModel = $this->customerRegistry->retrieve($customerId);
    return $customerModel->getDataModel();
}

It should works now.

Keep in mind to use repository and interface.

  • Wow, that was so easy, only changing the return annotation for the \Magento\User\Api\Data\UserInterface and it's working. I haven't changed the implementation, I see how it does with the customer, but uses this class: \Magento\Customer\Model\CustomerRegistry. In the user module that doesn't exist. Well I'll continue investigating, but using \Magento\User\Model\UserFactory seems it's working. – slayerbleast Jul 26 '17 at 7:33
  • It is the best practice to use the customer repository if you want to retrieve a customer by ID. – Franck Garnier Jul 27 '17 at 7:24
  • I don't know if I explained well, but I was creating an API for users, not customers. In fact I created the Users Repository... – slayerbleast Jul 27 '17 at 7:33
  • Ok understood, my bad. You are talking about Magento admin user ? So yes Magento did not have user repository, you can keep using factory so. Another tips for return API, if you do not want to manage the return type or if it is dynamically, you can use this : @return anyType from \Magento\Framework\Reflection\TypeProcessor – Franck Garnier Jul 27 '17 at 9:33
  • Yes, that was I meant. Oh, ty for the tip, I will try it :) – slayerbleast Jul 27 '17 at 10:12

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.