Hi
I am trying to create a custom download operation to a subresource collection and I am still struggling to understand the proper implementation. I have checked the documentation and some github support issue examples but still could not find any proper clear examples.
Here is the simplified version of my current implementation
<?php
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="AccountRepository")
* @ORM\Table(name="accounts")
*
* @ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER')"},
* itemOperations={
* "get_transactions_download"={
* "method"="GET",
* "path"="/accounts/{id}/download-transactions.{_format}",
* "controller"=DownloadTransactionsAction::class
* }
* },
* normalizationContext={
* "groups"={"read"}
* }
* )
*/
class Account
{
/**
* @ORM\OneToMany(targetEntity="Transaction", fetch="EXTRA_LAZY", mappedBy="account")
* @ApiSubresource(maxDepth=1)
*/
private $transactions;
}
/**
* @ORM\Entity(repositoryClass="TransactionRepository")
* @ORM\Table(name="account_transactions")
*
* @ApiResource(
* subresourceOperations={
* "api_accounts_transactions_get_subresource"={
* "method"="GET",
* "normalization_context"={"groups"={"read"}}
* }
* }
* )
* @ApiFilter(DateFilter::class, properties={"transactionDate"})
*/
class Transaction
{
/**
* @ORM\ManyToOne(targetEntity="Account", inversedBy="transactions", cascade={"remove"})
* @ORM\JoinColumn(name="account", nullable=false, onDelete="CASCADE")
*/
private $account;
/**
* @ORM\Column(name="transaction_date", type="datetime")
* @Groups({"read"})
*/
private $transactionDate;
}
Above implementation works fine without any problem and transactions can be requested from '/api/accounts/{id}/transactions.{_format}' url. So I am trying to implement a download feature to allow users to download the same collection as a csv file. (remove limit and pagination without removing the filtering options)
Current workaround
I am using a custom controller on the main resource entity and it seems more of a hack and I am missing the date filtering features of transaction resource.
Any help would be greatly appreciated!
remove limit and pagination without removing the filtering options
There is no support for per-operation filters.
But to force a download, just add a custom listener that adds the correct HTTP header on the Response, depending on the operation name.
Or just use a download query parameter? Saves you a lot of trouble.
Hi @teohhanhui , Thanks for the response and support :)! Interesting... I never thought about additional query parameters option. So we force a csv download instead of json without result limits.
json:
/api/accounts/{id}/transactions.{_format}?page=2&transactionDate[before]=2018-04-04
csv download:
/api/accounts/{id}/transactions.{_format}?transactionDate[before]=2018-04-04&download=1
Do you think it's possible? if it's possible at which point we modify the response?