Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Easy Api Bundle Laravel Package

citizen63000/easy-api-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require citizen63000/easy-api-bundle
    

    Enable the bundle in config/bundles.php:

    Citizen63000\EasyApiBundle\EasyApiBundle::class => ['all' => true],
    
  2. First Use Case: Create a CRUD controller for an entity (e.g., Post):

    // src/Controller/PostCrudController.php
    namespace App\Controller;
    
    use App\Entity\Post;
    use App\Form\Type\PostType;
    use Citizen63000\EasyApiBundle\Controller\AbstractApiController;
    
    class PostCrudController extends AbstractApiController
    {
        public const entityClass = Post::class;
        public const entityCreateTypeClass = PostType::class;
        public const entityUpdateTypeClass = PostType::class;
        public const serializationGroups = ['post:read'];
        public const listSerializationGroups = ['post:list'];
    
        use CrudControllerTrait;
    }
    
  3. Routing: Configure routes in config/routes.yaml:

    api_post:
        resource: "@App\Controller\PostCrudController.php"
        type: annotation
    
  4. Verify: Run php bin/console debug:router to confirm routes are registered (e.g., /api/post, /api/post/{id}).


Where to Look First

  • Documentation: Focus on the CrudControllerTrait and AbstractApiController in the source code.
  • Configuration: Check config/packages/easy_api.yaml (auto-generated after installation) for global settings like authentication or inheritance.
  • Entity Setup: Ensure your entity uses serialization groups (e.g., via @Groups in JMS Serializer or Symfony’s #[Groups]).

Implementation Patterns

Core Workflow

  1. Entity-Centric Development:

    • Define entityClass, entityCreateTypeClass, and entityUpdateTypeClass in the controller.
    • Use Symfony Forms (FormType) for input validation and transformation.
    • Leverage serialization groups (e.g., post:read, post:list) to control API output.
  2. CRUD Operations: The bundle auto-generates endpoints for:

    • GET /api/post (list with filters/sorting)
    • GET /api/post/{id} (retrieve)
    • POST /api/post (create)
    • PUT/PATCH /api/post/{id} (update)
    • DELETE /api/post/{id} (delete)
  3. Filtering and Sorting: Configure filterFields and filterSortFields in the controller to enable dynamic queries:

    public const filterFields = ['title', 'publishedAt'];
    public const filterSortFields = ['title', 'createdAt'];
    

    Clients can then use query params like ?filter[title]=hello&sort=-createdAt.

  4. Authentication: Enable global auth in config/packages/easy_api.yaml:

    easy_api:
        authentication: true
        user_class: App\Entity\User
    

    The bundle integrates with Symfony’s security system (e.g., JWT, API Token).

  5. Inheritance: Extend base classes for shared behavior:

    // src/Controller/AbstractApiController.php
    namespace App\Controller;
    
    use Citizen63000\EasyApiBundle\Controller\AbstractApiController as BaseController;
    
    abstract class AbstractApiController extends BaseController
    {
        // Custom logic (e.g., global serialization groups)
    }
    

    Update easy_api.inheritance.controller in config to point to this class.


Integration Tips

  1. Custom Actions: Extend the controller to add non-CRUD endpoints:

    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    
    class PostCrudController extends AbstractApiController
    {
        // ... existing CRUD constants ...
    
        #[Route('/api/post/{id}/publish', name: 'api_post_publish', methods: ['POST'])]
        public function publish(Post $post): Response
        {
            $post->setPublished(true);
            $this->getEntityManager()->flush();
            return $this->json(['status' => 'published']);
        }
    }
    
  2. Event Listeners: Hook into lifecycle events (e.g., prePersist, postUpdate) via Symfony’s event system:

    // src/EventListener/PostListener.php
    namespace App\EventListener;
    
    use Citizen63000\EasyApiBundle\Event\CrudEvent;
    use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
    
    #[AsEventListener(event: CrudEvent::PRE_PERSIST, method: 'onPrePersist')]
    class PostListener
    {
        public function onPrePersist(CrudEvent $event): void
        {
            $entity = $event->getEntity();
            $entity->setCreatedAt(new \DateTime());
        }
    }
    
  3. Testing: Use the built-in test helpers (if easy_api.tests.debug: true):

    use Citizen63000\EasyApiBundle\Tests\ApiTestTrait;
    
    class PostCrudControllerTest extends WebTestCase
    {
        use ApiTestTrait;
    
        public function testCreatePost(): void
        {
            $client = static::createClient();
            $response = $this->createEntity($client, Post::class, [
                'title' => 'Test Post',
                'content' => 'Hello, world!',
            ]);
            $this->assertResponseStatusCodeSame(201);
        }
    }
    
  4. Swagger/OpenAPI: The bundle supports OpenAPI annotations (@OA\*). Extend the base controller to add tags/descriptions:

    use OpenApi\Annotations as OA;
    
    #[OA\Tag(name: 'Posts')]
    class PostCrudController extends AbstractApiController
    {
        // ...
    }
    

Gotchas and Tips

Pitfalls

  1. Serialization Groups:

    • Issue: Missing serialization groups cause empty responses.
    • Fix: Ensure your entity uses #[Groups] (Symfony 5.3+) or @Groups (JMS Serializer):
      #[Groups(['post:read'])]
      private string $title;
      
    • Debug: Run php bin/console debug:serializer to verify groups.
  2. Form Types:

    • Issue: entityCreateTypeClass/entityUpdateTypeClass must extend AbstractType.
    • Fix: Use Symfony’s AbstractType or the bundle’s AbstractCoreType (if inheritance is configured).
  3. Authentication:

    • Issue: Global auth (easy_api.authentication: true) may break unauthenticated routes.
    • Fix: Exclude routes via @IsGranted or configure role-based access in the controller:
      use Symfony\Component\Security\Http Attribute\IsGranted;
      
      #[IsGranted('ROLE_USER')]
      class PostCrudController extends AbstractApiController { ... }
      
  4. Circular References:

    • Issue: Serialization fails with circular references (e.g., UserPost).
    • Fix: Use max_depth in serialization context or configure serialization.max_depth in config/packages/jms_serializer.yaml.
  5. Route Overrides:

    • Issue: Custom routes (e.g., /api/post/{id}/publish) may conflict with CRUD routes.
    • Fix: Use unique route names and avoid overlapping paths.

Debugging Tips

  1. Enable Debug Mode: Set easy_api.tests.debug: true in config/packages/easy_api.yaml to log requests/responses in tests.

  2. Check Events: Dump events in listeners to debug CRUD operations:

    #[AsEventListener(event: CrudEvent::PRE_PERSIST)]
    public function onPrePersist(CrudEvent $event): void
    {
        dump($event->getEntity(), $event->getRequest());
    }
    
  3. Validate Configuration: Run php bin/console debug:config easy_api to verify settings (e.g., user_class, inheritance).

  4. API Test Helper: Use ApiTestTrait to inspect responses:

    $response = $this->getEntity($client, Post::class, 1);
    $this->assertJson($response->getContent());
    

Extension Points

  1. Custom Controllers: Override AbstractApiController to modify default behavior (e.g., add global middleware):

    class CustomApiController extends AbstractApiController
    {
        public function __construct(private MyCustomService $service)
        {
            $this->service = $service;
        }
    }
    
  2. Dynamic Filtering: Extend filtering logic by overriding applyFilters() in the controller:

    protected function applyFilters(array $
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware