1

Magento2 : I checked the list of Magento2 open source. I followed the below API: /V1/categories/:categoryId/products

But this API giving only SKU, Position and Category ID of specific product. I want to fetch all the product details, like name,product description, price, tax details,image,etc. I have created custom API module, But I stucked in get and set methods of product attribute which I wanted to get in response.

1

/V1/categories/:categoryId/products::GET

\Magento\Catalog\Api\CategoryLinkManagementInterface::getAssignedProducts()

/**
 * {@inheritdoc}
 */
public function getAssignedProducts($categoryId)
{
    $category = $this->categoryRepository->get($categoryId);

    /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */
    $products = $category->getProductCollection();
    $products->addFieldToSelect('position');

    /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface[] $links */
    $links = [];

    /** @var \Magento\Catalog\Model\Product $product */
    foreach ($products->getItems() as $product) {
        /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface $link */
        $link = $this->productLinkFactory->create();
        $link->setSku($product->getSku())
            ->setPosition($product->getData('cat_index_position'))
            ->setCategoryId($category->getId());
        $links[] = $link;
    }
    return $links;
}

In order to customise that API, you should create a plugin for getAssignedProducts() and all fields you need into the product collection then set the data for $link property. For e.g:

/**
 * {@inheritdoc}
 */
public function aroundGetAssignedProducts(\Magento\Catalog\Api\CategoryLinkManagementInterface $subject, \Closure $proceed, $categoryId)
{
    $category = $this->categoryRepository->get($categoryId);

    /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */
    $products = $category->getProductCollection();
    $products->addFieldToSelect('position');
    $products->addFieldToSelect('some_data');
    $products->addFieldToFilter('some_data', ['in', $someConditions]);

    /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface[] $links */
    $links = [];

    /** @var \Magento\Catalog\Model\Product $product */
    foreach ($products->getItems() as $product) {
        /** @var \Magento\Catalog\Api\Data\CategoryProductLinkInterface $link */
        $link = $this->productLinkFactory->create();
        $link->setSku($product->getSku())
            ->setPosition($product->getData('cat_index_position'))
            ->setCategoryId($category->getId())
            ->setSomeData($product->getData('some_data');
        $links[] = $link;
    }
    return $links;
}

Cheers

  • To get and set method do I need to create any interface separately? If yes where and how to create? – Ashwini Sep 3 '18 at 6:47
  • @Ashwini \Magento\Catalog\Model\CategoryProductLink extends from \Magento\Framework\Api\AbstractExtensibleObject so you don't need to create new interface separately. – Toan Nguyen Sep 3 '18 at 6:49
  • can you please elaborate more..I am new in API customization. so I am following below url:inchoo.net/magento-2/magento-2-custom-api – Ashwini Sep 3 '18 at 7:28
  • or can you please edit the code above which files I need to create and how I will call the model and interface in di.xml – Ashwini Sep 3 '18 at 7:34
  • I try to fetch with the help of above method but whichever data set is not coming in response. – Ashwini Sep 4 '18 at 12:38
1

The below code will help you achieve this, as it is implementing new custom API to get all products against the given category using the getAssignedProducts function where you are not all getting products but the complete product information of your choice.

Step 1 – Create webapi.xml under your custom module \Scommerce\Custom\etc\

<route url="/V1/custom/:categoryId/products" method="GET">
    <service class="Scommerce\Custom\Api\CategoryLinkManagementInterface" method="getAssignedProducts" />
    <resources>
        <resource ref="self"/>
    </resources>
</route>

Step 2 – Lets now create the main interface file for our web API

CategoryLinkManagementInterface.php under Scommerce\Custom\Api\ as specified in webapi.xml in Step 1

namespace Scommerce\Custom\Api;

/**
 * @api
 */
interface CategoryLinkManagementInterface
{
    /**
     * Get products assigned to a category
     *
     * @param int $categoryId
     * @return \Scommerce\Custom\Api\Data\CategoryProductLinkInterface[]
     */
    public function getAssignedProducts($categoryId);
}

Step 3 – Based on the return parameter in Step 2, let’s create our data interface CategoryProductLinkInterface.php under \Scommerce\Custom\Api\Data\

namespace Scommerce\Custom\Api\Data;

/**
 * @api
 */
interface CategoryProductLinkInterface
{
    /**
     * @return string|null
     */
    public function getSku();

    /**
     * @param string $sku
     * @return $this
     */
    public function setSku($sku);

    /**
     * @return string|null
     */
    public function getName();

    /**
     * @param string $name
     * @return $this
     */
    public function setName($name);

    /**
     * @return float|null
     */
    public function getPrice();

    /**
     * @param float $price
     * @return $this
     */
    public function setPrice($price);

    /**
     * @return int|null
     */
    public function getPosition();

    /**
     * @param int $position
     * @return $this
     */
    public function setPosition($position);

    /**
     * @return string|null
     */
    public function getCategoryDescription();

    /**
     * @param string $description
     * @return $this
     */
    public function setCategoryDescription($description);
}

Step 4 – Now our interface files are created, let’s create our model classes where we can put the actual business logic, to do so we would need to specify this in our di.xml file under \Scommerce\Custom\etc\

<config ...>
    <preference for="Scommerce\Custom\Api\CategoryLinkManagementInterface" type="Scommerce\Custom\Model\CategoryLinkManagement" />
    <preference for="Scommerce\Custom\Api\Data\CategoryProductLinkInterface" type="Scommerce\Custom\Model\CategoryProductLink" />
</config>

Step 5 – Let’s create our first model class CategoryLinkManagement.php under Scommerce\Custom\Model\ as specified in di.xml

namespace Scommerce\Custom\Model;

/**
 * Class CategoryLinkManagement
 */
class CategoryLinkManagement implements \Scommerce\Custom\Api\CategoryLinkManagementInterface
{
    /**
     * @var \Magento\Catalog\Api\CategoryRepositoryInterface
     */
    protected $categoryRepository;

    /**
     * @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory
     */
    protected $productLinkFactory;

    /**
     * CategoryLinkManagement constructor.
     *
     * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
     * @param \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory $productLinkFactory
     */
    public function __construct(
        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
        \Scommerce\Custom\Api\Data\CategoryProductLinkInterfaceFactory $productLinkFactory
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->productLinkFactory = $productLinkFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function getAssignedProducts($categoryId)
    {
        $category = $this->categoryRepository->get($categoryId);
        if (!$category->getIsActive()) {
            return [[
                'error' => true,
                'error_desc' => 'Category is disabled'
            ]];
        }
        $categoryDesc = $category->getDescription();

        /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $products */
        $products = $category->getProductCollection()
            ->addFieldToSelect('position')
            ->addFieldToSelect('name')
            ->addFieldToSelect('price');

        /** @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterface[] $links */
        $links = [];

        /** @var \Magento\Catalog\Model\Product $product */
        foreach ($products->getItems() as $product) {
            /** @var \Scommerce\Custom\Api\Data\CategoryProductLinkInterface $link */
            $link = $this->productLinkFactory->create();
            $link->setSku($product->getSku())
                ->setName($product->getName())
                ->setPrice($product->getFinalPrice())
                ->setPosition($product->getData('cat_index_position'))
                ->setCategoryDescription($categoryDesc);
            $links[] = $link;
        }

        return $links;
    }
}

Step 6 – Lets now create our second model class CategoryProductLink.php under Scommerce\Custom\Model\ as specified in di.xml

namespace Scommerce\Custom\Model;

/**
 * @codeCoverageIgnore
 */
class CategoryProductLink implements \Scommerce\Custom\Api\Data\CategoryProductLinkInterface
{
    /**#@+
     * Constant for confirmation status
     */
    const KEY_SKU                   = 'sku';
    const KEY_NAME                  = 'name';
    const KEY_PRICE                 = 'price';
    const KEY_CATEGORY_DESC         = 'category_description';
    const KEY_POSITION              = 'position';
    /**#@-*/

    /**
     * {@inheritdoc}
     */
    public function getSku()
    {
        return $this->_get(self::KEY_SKU);
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return $this->_get(self::KEY_NAME);
    }

    /**
     * {@inheritdoc}
     */
    public function getPosition()
    {
        return $this->_get(self::KEY_POSITION);
    }

    /**
     * {@inheritdoc}
     */
    public function getPrice()
    {
        return $this->_get(self::KEY_PRICE);
    }

    /**
     * {@inheritdoc}
     */
    public function getCategoryDescription()
    {
        return $this->_get(self::KEY_CATEGORY_DESC);
    }

    /**
     * @param string $sku
     * @return $this
     */
    public function setSku($sku)
    {
        return $this->setData(self::KEY_SKU, $sku);
    }

    /**
     * @param string $name
     * @return $this
     */
    public function setName($name)
    {
        return $this->setData(self::KEY_NAME, $name);
    }

    /**
     * @param int $position
     * @return $this
     */
    public function setPosition($position)
    {
        return $this->setData(self::KEY_POSITION, $position);
    }

    /**
     * @param float $price
     * @return $this
     */
    public function setPrice($price)
    {
        return $this->setData(self::KEY_PRICE, $price);
    }

    /**
     * @param string $description
     * @return $this
     */
    public function setCategoryDescription($description)
    {
        return $this->setData(self::KEY_CATEGORY_DESC, $description);
    }

}

The above will allow us to call our first Magento 2 web API using the customer token. To retrieve admin or custom token, please have a look at Magento official token retrieval documentation

source: https://www.scommerce-mage.com/blog/magento-2-how-to-create-custom-api.html

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.