Magento – Magento2: How to create custom API to get all product details of specific category

magento2.2.2rest api

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.

Best Answer

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