check24 / apitk-manipulation-bundle
Installs: 3 669
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 4
Forks: 4
Type:symfony-bundle
Requires
- php: ^7.4 || ^8.0
- check24/apitk-common-bundle: ^2.2.0
- doctrine/doctrine-bundle: ^2.2
- doctrine/orm: ^2.5
- doctrine/persistence: ^2
- nelmio/api-doc-bundle: ^3.2
- sensio/framework-extra-bundle: ^5.2
- symfony/config: >= 5.3 <6.0
- symfony/dependency-injection: >= 5.3 <6.0
- symfony/form: >= 5.3 <6.0
- symfony/framework-bundle: >= 5.3 <6.0
Requires (Dev)
- captainhook/captainhook: ^5.0
- captainhook/plugin-composer: ^5.1
- friendsofphp/php-cs-fixer: ^2.12
- phpmd/phpmd: ^2.6
- phpstan/phpstan: ^0.12
- phpstan/phpstan-deprecation-rules: ^0.12.6
- phpunit/phpunit: ^9.3
- roave/security-advisories: dev-latest
- symfony/phpunit-bridge: >= 4.3 <6.0
This package is auto-updated.
Last update: 2024-12-05 02:01:20 UTC
README
API Toolkit Bundle to handle POST, PUT, PATCH and DELETE methods.
Installation
Install the package via composer:
composer require check24/apitk-manipulation-bundle
Usage
Example Classes
See the example
-Folder in this repository: https://github.com/alexdo/apitk-manipulation-bundle/tree/master/example
User entity
namespace MyApp\Entity; use Symfony\Component\Validator\Constraints as Assert; class User { private $id; /** * @Assert\NotBlank() */ private $username; /** * @Assert\NotBlank() * @Assert\Email() */ private $email; /** * @Assert\NotBlank() */ private $fullname; // ... }
User FormType
namespace MyApp\Form\Type; use MyApp\Entity\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class UserV1Type extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('username', TextType::class) ->add('email', EmailType::class) ->add('fullname', TextType::class); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults( [ 'data_class' => User::class, ] ); } }
Controller
namespace MyApp\Controller; use FOS\RestBundle\Controller\Annotations as Rest; use MyApp\Entity\User; use Shopping\ApiTKManipulationBundle\Annotation as Manipulation; use Swagger\Annotations as SWG; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response; class UserV1Controller extends Controller { /** * Create a new user. * * @Rest\Post("/v1/users/{id}") * @Manipulation\Update("user", type=UserV1Type::class) * * @SWG\Tag(name="User") * * @param User $user * * @return Response */ public function postUserV1(User $user): Response { return new Response('', 200); } /** * Update all properties of a given user. * * @Rest\Put("/v1/users/{id}") * @Manipulation\Update("user", type=UserV1Type::class) * * @SWG\Tag(name="User") * * @param User $user * * @return Response */ public function putUserV1(User $user): Response { return new Response('', 200); } /** * Partially update a users's properties. * * @Rest\Patch("/v1/users/{id}") * @Manipulation\Update("user", type=UserV1Type::class) * * @SWG\Tag(name="User") * * @param User $user * * @return Response */ public function patchUserV1(User $user): Response { return new Response('', 200); } /** * Remove a user. * * @Rest\Delete("/v1/user/{id}") * * @Manipulation\Delete("id", entity=User::class) * * @SWG\Tag(name="User") * * @return Response */ public function deleteUserV1(Response $response): Response { return $response; } }
Updating Entities (POST, PUT, PATCH)
Updating entites works by mapping request data to a form, validating it and then persisting the form's data to the Database via Doctrine.
You'll need:
- Doctrine Entity
- Form Type with data_class
- Controller Action
use Shopping\ApiTKManipulationBundle\Annotation as Manipulation; /** * Partially update a users's properties. * * @Rest\Patch("/v1/users/{id}") * @Manipulation\Update("user", type=UserV1Type::class) * * @SWG\Tag(name="User") * * @param User $user * * @return Response */ public function patchUserV1(User $user): Response { return new Response('', 200); }
This will also auto-generate appropriate Swagger parameters. Usage of FOSRest bundle is optional. Controller methods look the same for POST and PUT.
The $user
parameter is an already updated version of the requested User. You can do anything you want with it:
Serialization, JSON encode, etc.
Internally, the Update
annotation fetches the default
EntityManager, gets the Repository and executes find($id)
on it. You can customize this in three ways:
-
If you'd like to use a different ORM connection than
default
, supply it viaentityManager
:@Manipulation\Update("user", type=UserV1Type::class, entityManager="custom")
This will cause the annotation to fetch the repository and entity from the "custom" EntityManager.
-
If you'd like to use a different Repository method than
find
, use themethodName
option:@Manipulation\Update("user", type=UserV1Type::class, methodName="findById")
-
If your path component is something different than
id
, eg.email
, you can supply the parameter to use via therequestParam
option:@Manipulation\Update("user", type=UserV1Type::class, requestParam="email", methodName="findByEmail")
Removing Entities (DELETE)
To remove an entity, add an action to your controller that uses the Delete
-Annotation.
use Shopping\ApiTKManipulationBundle\Annotation as Manipulation; /** * Remove a user. * * @Rest\Delete("/v1/user/{id}") * * @Manipulation\Delete("id", entity=User::class) * * @SWG\Tag(name="User") * * @return Response */ public function deleteUserV1(Response $response): Response { return $response; }
@Manipulation\Delete("id", entity=User::class)
"id"
is the name of the path-component to get the ID fromentity=User::class
is the type of the entity to be removed
The $response
parameter is a HTTP 204-Response (No Content). You can just return it, or ignore
it and build one of your own.
Delete
will, by default, perform a hard delete by executing find($id)
on UserRepository
and then
removing the Entity via ObjectManager::remove
.
As with Update
, you can customize this behaviour:
-
If you'd like to perform a soft delete or other things instead, use the
methodName
option:@Manipulation\Delete("id", entity=User::class, methodName="deleteById")
This will cause the Annotation to call
DeleteRepository::deleteById(DeletionService $deletionService)
. TheDeletionService
allows you to access all request parameters. Perform anything you want to mark your Entity as deleted, eg. setting a deleted-Property from 0 to 1 and then flushing the EntityManager. -
If you'd like to use a different ORM connection than
default
, supply it viaentityManager
:@Manipulation\Delete("id", entity=User::class, entityManager="custom")
This will cause the annotation to operate against the "custom" EntityManager.