dev-master
9999999-dev
The Requires
- symfony/framework-bundle 2.1.*
- friendsofsymfony/rest-bundle dev-master
- php >=5.4.0
- jms/serializer-bundle 0.9.*
The Development Requires
Wallogit.com
2017 © Pedro Peláez
This bundle will generate a REST HATEOAS api based on the configuration you'll do. ATM it can only generate a read only api, backed by doctrine ORM. The representations are optimized for the XML format, but are also usable in JSON., (*2)
If you create relations between resources, the bundle will automatically create links between them., (*3)
The design obviously took many shortchuts, and is not a reference of OOP design ... but it works. But it's easy to override behavior because you need to the extend the classe that does everything, for each resource..., (*4)
This bundle was extracted from an app, and need some love to be usable. (ie composer, make tests work etc ...), (*5)
MIT: Resources/meta/LICENSE, (*6)
Edit your composer.json like this:, (*7)
{
"require": {
...
"jms/serializer-bundle": "dev-xml-attribute-map as 0.9.0",
"fsc/rest-bundle": "*"
...
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/adrienbrault/JMSSerializerBundle"
}
]
}
Update your deps: composer update., (*8)
Add the bundle to your AppKernel:, (*9)
// in AppKernel::registerBundles()
$bundles = array(
// ...
new FSC\RestBundle\FSCRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new FOS\FOSRestBundle(),
// ...
);
Be aware that this bundle relies on a fork of JMSSerializerBundle, because this PR is still not merged: https://github.com/schmittjoh/JMSSerializerBundle/pull/164, (*10)
For an example of what the controller returns: https://gist.github.com/3800069, (*11)
You need to define services, tagged with fsc_rest.resource., (*12)
services:
fsc.core.spot.resource.spots:
class: FSC\Core\SpotBundle\REST\SpotsResource
parent: fsc.rest.resource.abstract_doctrine
tags:
- { name: fsc_rest.resource }
<?php
namespace FSC\Core\TeamBundle\REST;
use FSC\Core\MainBundle\REST\AbstractSocialEntityResource;
use FSC\Common\RestBundle\Form\Model\Collection;
use FSC\Core\TeamBundle\Repository\FormationRepository;
use FSC\Core\SpotBundle\Repository\SpotRepository;
class TeamsResource extends AbstractSocialEntityResource
{
protected function configure()
{
return array_merge(parent::configure(), array(
'prefix' => '/teams',
'entity_class' => 'FSC\Core\TeamBundle\Entity\Team',
));
}
// Configure root collection ... /teams
protected function configureCollection()
{
return array_merge(parent::configureCollection(), array(
'xml_root_name' => 'teams',
'representation_class' => 'FSC\Core\TeamBundle\Model\Representation\Teams',
'pager_fetch_join_collection' => false,
));
}
// Configure how each entity representation looks like
// ie:
//
// <team id="">
// <name></name>
// ...
// </team>
protected function configureEntity()
{
return array_merge(parent::configureEntity(), array(
'expanded_collections' => array('formations'),
'xml_root_name' => 'team',
'normalize_attributes' => array(
'id' => 'id',
),
'normalize_elements' => array(
'name' => 'name',
'clubName' => 'clubName',
'category' => 'category',
'division' => 'division',
'foundedAt' => 'foundedAt',
),
));
}
// Configure each entity collection, ie: a teams has formations, so you'll have a collection
// at /teams/{id}/formations
protected function configureEntityCollections()
{
return array_merge_recursive(parent::configureEntityCollections(), array(
'formations' => array(
'representation_class' => 'FSC\Core\TeamBundle\Model\Representation\Formations',
// Which resources should be asked to normalize the collection elements ...
'resources' => array(
'FSC\Core\TeamBundle\Entity\Formation' => 'fsc.core.team.resource.formations',
),
'create_qb' => function ($em, $repository, $entity) {
$formationRepository = $em->getRepository('FSCCoreTeamBundle:Formation'); /** @var $formationRepository FormationRepository */
return $formationRepository->createSelectByTeamQB($entity);
},
),
'official-spots' => array(
'representation_class' => 'FSC\Core\SpotBundle\Model\Representation\Spots',
'resources' => array(
'FSC\Core\SpotBundle\Entity\Spot' => 'fsc.core.spot.resource.spots',
),
'create_qb' => function ($em, $repository, $team) {
$spotRepository = $em->getRepository('FSCCoreSpotBundle:Spot'); /** @var $spotRepository SpotRepository */
return $spotRepository->createSelectNonDeletedByOfficialTeamQB($team);
},
),
));
}
}
<?php
namespace FSC\Core\SpotBundle\REST;
use FSC\Core\MainBundle\REST\AbstractSocialEntityResource;
use FSC\Common\RestBundle\Form\Model\Collection;
use FSC\Core\TeamBundle\Repository\TeamRepository;
class SpotsResource extends AbstractSocialEntityResource
{
protected function configure()
{
return array_merge(parent::configure(), array(
'prefix' => '/spots',
'entity_class' => 'FSC\Core\SpotBundle\Entity\Spot',
));
}
protected function configureCollection()
{
return array_merge(parent::configureCollection(), array(
'xml_root_name' => 'spots',
'representation_class' => 'FSC\Core\SpotBundle\Model\Representation\Spots',
'pager_fetch_join_collection' => false,
));
}
protected function configureEntity()
{
return array_merge(parent::configureEntity(), array(
'xml_root_name' => 'spot',
'normalize_attributes' => array(
'id' => 'id',
),
'normalize_elements' => array(
'name' => 'name',
'description' => 'description',
'subCategory' => 'subCategory',
'category' => 'category',
'surface' => 'surface',
'previousNames' => 'previousNames',
'capacity' => 'capacity',
'facts' => 'facts',
'opened' => 'opened',
'architect' => 'architect',
),
));
}
protected function configureEntityCollections()
{
return array_merge_recursive(parent::configureEntityCollections(), array(
'official-teams' => array(
'representation_class' => 'FSC\Core\TeamBundle\Model\Representation\Teams',
'resources' => array(
'FSC\Core\TeamBundle\Entity\Team' => 'fsc.core.team.resource.teams',
),
'create_qb' => function ($em, $repository, $spot) {
$teamRepository = $em->getRepository('FSCCoreTeamBundle:Team'); /** @var $teamRepository TeamRepository */
return $teamRepository->createSelectByOfficialSpotQB($spot);
},
),
));
}
protected function configureEntityRelations()
{
return array_merge(parent::configureEntityRelations(), array(
'creator' => array(
'get_relation' => function ($em, $repository, $spot) {
return $spot->getSpotCreator();
},
'resources' => array(
'FSC\Core\UserBundle\Entity\User' => 'fsc.core.user.resource.users',
),
),
));
}
}
When you request a resource, the bundle will:, (*13)
Entity --(normalize)--> Representation --(serialize)--> XML/JSON
|| ||
RESTResources JMSSerializer