kami / api-core-bundle
This bundle provides you with easy and flexible REST CRUDs creation
Installs: 2 585
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 2
Forks: 0
Open Issues: 0
Type:symfony-bundle
Requires
- php: ^7.1
- doctrine/doctrine-bundle: ^1.3
- doctrine/orm: ^2.5 || ^2.7
- jms/serializer-bundle: ^2.4
- kami/request-processor: dev-master
- pagerfanta/pagerfanta: ^2.0
- symfony/form: ^2.8 || ^3.0 || ^4.0
- symfony/framework-bundle: ^2.8 || ^3.0 || ^4.0
- symfony/security-bundle: ^2.8 || ^3.0 || ^4.0
- symfony/validator: ^2.8 || ^3.0 || ^4.0
- symfony/yaml: ^2.8 || ^3.0 || ^4.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.2
- nelmio/api-doc-bundle: ^3.2
- phpunit/phpunit: ^4.8.35|^5.7.11|^6.5
- swiftmailer/swiftmailer: ^4.3 || ^5.0 || ^6.0
- symfony/console: ^2.8 || ^3.0 || ^4.0
- symfony/phpunit-bridge: ^2.8 || ^3.0 || ^4.0
This package is auto-updated.
Last update: 2024-11-05 21:10:57 UTC
README
This bundle provides easiest way to create CRUD actions in your REST applications. Simple and flexible configuration for each resource included.
Installation
Installation is easy. You just follow these sipmle steps
Require it
composer require kami/api-core-bundle
Add it to your kernel
<?php // AppKernel.php public function registerBundles() { $bundles = [ ... new Kami\ApiCoreBundle\KamiApiCoreBundle(), ... ]; }
Configuration
Add your resources
# app/config/config.yml kami_api_core: locales: ['en', 'de'] resources: - { name: your-resource-name, entity: AppBundle\Entity\YourEntiy }
Add KamiApiCore routing loader
kami_api_core: resource: '@KamiApiCoreBundle/Resources/config/routing.xml'
Now you are good to go.
Workflow
Routing loader
Bundle will generate 5 routes for each resource you specified in your config
GET /api/your-resource-name
- Index routeGET /api/your-resource-name/{id}
- Get single resourceGET /api/your-resource-name/filter
- Filter resourcePOST /api/your-resource-name
- Create resourcePUT /api/your-resource-name/{id}
- Update resourceDELETE /api/your-resource-name/{id}
- Delete resource
Optionally if resource entity implements KamiApiCoreBundle\Model\UserAwareInterface
additonal route will be generated
GET /api/my/your-resource-name
- Get resources belonged to current user
Note! You must clear your cache after modifying your resources
Access rules
You have to define access rules in your entity using annotations. By default all resources have restricted access. You must explicitly grant access to each user role.
Strategies
Bundle utilizes Strategy pattern and has default strategy for each route You can override any of strategy by resource configuration:
Example
# app/config/config.yml kami_api_core: locales: ['en', 'de'] resources: - name: your-resource-name entity: AppBundle\Entity\YourEntiy strategies: index: "%my_awesome_index_strategy%" filter: "%my_awesome_filter_strategy%" item: "%my_awesome_item_strategy%" create: "%my_awesome_create_strategy%" update: "%my_awesome_update_strategy%" delete: "%my_awesome_delete_strategy%"
Default strategies
Default strategies are using following steps:
Index
- get_reflection_from_request
- validate_resource_access
- get_query_builder
- build_select_query
- sort
- paginate
- serialize_response_data
Item
- get_reflection_from_request
- validate_resource_access
- get_query_builder
- build_select_query
- item_add_where
- item_set_selected_data
- serialize_response_data
Create
- get_reflection_from_request
- validate_resource_access
- get_entity_from_reflection
- build_create_form
- handle_request
- validate_form
- persist
- trim_response
- serialize_response_data
Update
- get_reflection_from_request
- validate_resource_access
- fetch_entity_by_id
- build_update_form
- handle_request
- validate_form
- persist
- trim_response
- serialize_response_data
Delete
- get_reflection_from_request
- validate_resource_access
- fetch_entity_by_id
- delete
Filter
- get_reflection_from_request
- validate_resource_access
- get_query_builder
- build_select_query
- validate_filters
- filter
- sort
- paginate
- serialize_response_data
Adding custom steps
To add custom step just extend Kami\ApiCoreBundle\RequestProcessor\Step\AbstractStep
Example:
<?php namespace Acme\AppBundle\Step; use Kami\ApiCoreBundle\RequestProcessor\Step\AbstractStep; class MyStep extends AbstractStep { public function execute() { // Do your stuff here return $this->createResponse(['your_data' => $data]); } public function requiresBefore() { return [MyStep::class]; } }
# services.yml my_awesome_step: class: Acme\AppBundle\Step\MyStep arguments: - "@service" - ... tags: - { name: kami_api_core.strategy_step, shortcut: "my_step" }
Form generation
Default strategy will generate forms for both POST
and PUT
actions.
Only accessible fields for current user will be included.
See @CanBeCreatedBy
, @CanBeEditedBy
, @AnonymousCreate
, @AnonymousEdit
and @Form
in annotation reference.
Request body converter
Most frontend libraries send form data as json. Bundle converts this payload and injects parameters to request data
Filters
GET /api/your-resource-name/filter
endpoint accepts query param filter
,
it should contain base64 encoded json payload with applied filters
Available filters with examples
Available filters are:
eq
- Equalsgt
- Greater thanlt
- Lower thanlk
- Likebw
- Between
Examples
// Equals {"type": "eq", "property": "id", "value": 1}] // Greater than {"type": "gt", "property": "id", "value": 3}] // Lower than {"type": "lt", "property": "id", "value": 3}] // Like {"type": "lk", "property": "title", "value": "foo"}] // Between {"type": "bw", "property": "id", "min": 1, "max": 5}]
Sort
You can sort index
and filter
route responses using sort
and direction
query params.
sort
parameter should represent field of your entity, while direction
can be either asc
or desc
Example
GET /api/your-resource-name?sort=property&direction=desc
Annotations reference
@Access
Defines roles that can access the resource or property
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; class YourEntity { ... /** * @Access({"ROLE_USER", "ROLE_ADMIN"}) * @ORM\Column(name="property", type="string", length=255) */ private $property; ... }
@AnonymousAccess
Defines anonymous access to the resource
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; /** * @Api\AnonymousAccess */ class YourEntity { ... /** * @ORM\Column(name="property", type="string", length=255) * @Api\AnonymousAccess */ private $property; ... }
@AnonymousCreate
Defines if anonymous users can create the resource
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; /** * @Api\AnonymousCreate */ class YourEntity { ... /** * @ORM\Column(name="property", type="string", length=255) * @Api\AnonymousCreate */ private $property; ... }
@AnonymousEdit
Defines if anonymous users can edit the resource
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; /** * AnonymousUpdate */ class YourEntity { ... /** * @ORM\Column(name="property", type="string", length=255) */ private $property; ... }
@CanBeCreatedBy
Defines roles that can create the resource or property
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; /** * @Api\CanBeCreatedBy({"ROLE_USER", "ROLE_ADMIN"}) */ class YourEntity { ... /** * @Api\CanBeCreatedBy({"ROLE_USER", "ROLE_ADMIN"}) * @ORM\Column(name="property", type="string", length=255) */ private $property; ... }
@CanBeEditedBy
Defines roles that can update the resource or property
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; /** * CanBeUpdatedBy({"ROLE_USER", "ROLE_ADMIN"}) */ class YourEntity { ... /** * @Api\CanBeUpdatedBy({"ROLE_USER", "ROLE_ADMIN"}) * @ORM\Column(name="property", type="string", length=255) */ private $property; ... }
@Form
Used to define form options. Accepts two arguments: type
and options
. See
Symfony Form component documentation
Usage example
<?php namespace AppBundle\Entity; use Kami\ApiCoreBundle\Annotation as Api; class YourEntity { ... /** * @Api\Form(type="Symfony\Component\Form\Extension\Core\Type\DateTimeType", options={"widget": "single_text"}) * @ORM\Column(name="property", type="datetime") */ private $property; ... }