dmytrof / fractal-bundle
Symfony FractalBundle
1.2
2021-06-16 16:38 UTC
Requires
- php: ^7.2 || ^8.0
- ext-json: *
- doctrine/collections: ^1.6
- league/fractal: ^0.18
- symfony/framework-bundle: ^3.4 || ^4.3 || ^5.0
Requires (Dev)
- friendsofsymfony/rest-bundle: ^2.2 || ^3.0
- phpunit/phpunit: ^8.3 || ^9.1
Suggests
- friendsofsymfony/rest-bundle: Adds support for using Fractal with FOSRestBundle
- league/fractal: Allows more advanced using of Fractal
README
本捆绑包帮助您将 League 的 Fractal 集成到您的 Symfony 3/4/5 应用程序中
安装
步骤 1: 安装捆绑包
$ composer require dmytrof/fractal-bundle
步骤 2: 启用捆绑包
Symfony 3
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Dmytrof\FractalBundle\DmytrofFractalBundle(),
// ...
);
}
Symfony 4/5
<?php
// config/bundles.php
return [
// ...
Dmytrof\FractalBundle\DmytrofFractalBundle::class => ['all' => true],
];
用法
在开始使用此捆绑包之前,请先阅读官方的 Fractal 文档
1.基本用法
假设您有一些模型 文章
<?php
namespace App\Model;
use App\Model\Author;
class Article
{
/**
* @var int
*/
protected $id;
/**
* @var Author
*/
protected $author;
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $body;
/**
* @var \DateTime
*/
protected $publishedAt;
/**
* Returns id
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* Sets id
* @param int|null $id
* @return $this
*/
public function setId(?int $id): Article
{
$this->id = $id;
return $this;
}
/**
* Returns author
* @return Author|null
*/
public function getAuthor(): ?Author
{
return $this->author;
}
/**
* Sets author
* @param Author|null $author
* @return Article
*/
public function setAuthor(?Author $author): Article
{
$this->author = $author;
return $this;
}
// ...
// Other Setters and Getters
// ...
/**
* Returns published at date
* @return \DateTime|null
*/
public function getPublishedAt(): ?\DateTime
{
return $this->publishedAt;
}
/**
* Sets published at date
* @param \DateTime|null $publishedAt
* @return Article
*/
public function setPublishedAt(?\DateTime $publishedAt): Article
{
$this->publishedAt = $publishedAt;
return $this;
}
}
和 作者
<?php
namespace App\Model;
class Author
{
/**
* @var int
*/
protected $id;
/**
* @var string
*/
protected $firstName;
/**
* @var string
*/
protected $lastName;
/**
* @var string
*/
protected $email;
/**
* Returns id
* @return int|null
*/
public function getId(): ?int
{
return $this->id;
}
/**
* Sets id
* @param int|null $id
* @return Author
*/
public function setId(?int $id): Author
{
$this->id = $id;
return $this;
}
// ...
// Other Getters and Setters
// ...
}
为您的实体创建转换器
AuthorTransformer
<?php
namespace App\FractalTransformer;
use App\Model\Author;
use Dmytrof\FractalBundle\Transformer\AbstractTransformer;
class AuthorTransformer extends AbstractTransformer
{
// Model which is handled by this transformer
protected const SUBJECT_CLASS = Author::class;
/**
* @var bool
*/
protected $showShortInfo = false;
/**
* @return bool
*/
public function isShowShortInfo(): bool
{
return $this->showShortInfo;
}
/**
* Sets show short info
* @param bool $showShortInfo
* @return AuthorTransformer
*/
public function setShowShortInfo(bool $showShortInfo = true): AuthorTransformer
{
$this->showShortInfo = $showShortInfo;
return $this;
}
/**
* Transforms Author to array
* @param Author $subject
* @return array
*/
public function transformSubject($subject): array
{
$data = [
'id' => $subject->getId(),
'firstName' => $subject->getFirstName(),
'lastName' => $this->isShowShortInfo() ? substr($subject->getLastName(), 0, 1).'.' : $subject->getLastName(),
];
if (!$this->isShowShortInfo()) {
$data['email'] = $subject->getEmail();
}
return $data;
}
}
和 ArticleTransformer
<?php
namespace App\FractalTransformer;
use App\Model\Article;
use Dmytrof\FractalBundle\Transformer\AbstractTransformer;
use League\Fractal\Resource\{Item, ResourceInterface};
class ArticleTransformer extends AbstractTransformer
{
// Model which is handled by this transformer
protected const SUBJECT_CLASS = Article::class;
protected $defaultIncludes = [
'author'
];
protected $availableIncludes = [
'body',
];
/**
* Transforms Article to array
* @param Article $subject
* @return array
*/
public function transformSubject($subject): array
{
return [
'id' => $subject->getId(),
'title' => $subject->getTitle(),
'publishedAt' => $this->transformDateTime($subject->getPublishedAt()),
];
}
/**
* Includes author
* @param Article $article
* @return Item
*/
public function includeAuthor(Article $article): Item
{
return $this->item($article->getAuthor(), AuthorTransformer::class);
}
/**
* Includes body
* @param Article $article
* @return ResourceInterface
*/
public function includeBody(Article $article): ResourceInterface
{
return $this->primitive($article->getBody());
}
}
更新控制器
<?php
namespace App\Controller\Api\v1;
use App\Model\Article;
use App\FractalTransformer\ArticleTransformer;
use Dmytrof\FractalBundle\Service\FractalManager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\{Request, JsonResponse};
/**
* @Route("/api/v2/articles")
*/
class ArticleController extends AbstractController
{
/**
* @Route("/{id<\d+>}", methods={"GET"})
*/
public function getOne(int $id, Request $request, FractalManager $fractalManager)
{
$model = $this->getArticeById($id); // Some method to receive model
$fractalManager
->parseIncludes($request->get('include', ''))
->parseExcludes($request->get('exclude', ''))
->parseFieldsets($request->get('fieldsets', []))
;
return new JsonResponse([
'data' => $fractalManager->getModelData($model, ArticleTransformer::class),
], JsonResponse::HTTP_OK);
}
}