Weave 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

Melodiia Laravel Package

biig/melodiia

Melodiia is a Symfony toolkit for building JSON:API-compliant REST APIs without magic: Swagger documentation endpoint, CRUD controllers, Symfony Form input, error handling, and standardized API responses. Requires PHP 8.0+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Requirements (as of 0.12.2)

    • PHP 8.1+ with Symfony 6.4 / 7.x / 8.x (Symfony 8 support was fixed in 0.12.2).
    • Doctrine ORM 2.x or 3.x — ORM 3 support and pagerfanta/doctrine-orm-adapter ^4 arrived in 0.12.2.
    • If you are on ORM 3, you must also be on the Pagerfanta adapter 4 line; the older adapter versions are not ORM 3 compatible.
  2. Installation

    composer require swag-industries/melodiia
    

    This auto-generates melodiia.yaml in config/.

  3. First Use Case: Basic CRUD Endpoint

    • Define a Symfony Form for your entity (e.g., PostType):
      // src/Form/PostType.php
      use Symfony\Component\Form\AbstractType;
      use Symfony\Component\Form\FormBuilderInterface;
      
      class PostType extends AbstractType {
          public function buildForm(FormBuilderInterface $builder, array $options) {
              $builder
                  ->add('title', TextType::class)
                  ->add('content', TextareaType::class);
          }
      }
      
    • Annotate your entity with #[Melodiia\Resource]:
      // src/Entity/Post.php
      use Melodiia\Resource;
      
      #[Resource(formType: PostType::class)]
      class Post {}
      
    • No controller needed—Melodiia auto-generates CRUD routes (/api/posts).
  4. Test the API

    • Visit /api/docs for Swagger UI.
    • Send a POST to /api/posts with JSON payload:
      {"title": "Hello", "content": "World"}
      
    • Response adheres to JSON:API spec.

Note for Laravel developers: Melodiia is a Symfony bundle, not a Laravel package. You cannot composer require it into a Laravel app and expect melodiia.yaml, auto-routed controllers, or Symfony Forms to work under Laravel's container. Day-to-day leverage only applies if you maintain a Symfony service (or a hybrid stack with a Symfony API boundary) alongside your Laravel code. If your stack is Laravel-only, treat this assessment as a reference for the JSON:API/Form-driven pattern, not as droppable code.


Implementation Patterns

1. Form-Driven API Design

  • Pros: Reuse Symfony Forms for validation, transformation, and documentation.
  • Pattern:
    // src/Form/UserType.php
    class UserType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults([
                'csrf_protection' => false, // Disable for APIs
                'validation_groups' => ['Default', 'api'],
            ]);
        }
    }
    
  • Tip: Use validation_groups to separate API-specific rules (e.g., api).

2. Customizing Responses

  • Override default JSON:API responses via event subscribers:
    // src/EventSubscriber/CustomResponseSubscriber.php
    use Melodiia\Event\ResourceEvent;
    
    class CustomResponseSubscriber implements EventSubscriberInterface {
        public static function getSubscribedEvents() {
            return [
                ResourceEvent::PRE_SERIALIZE => 'onPreSerialize',
            ];
        }
    
        public function onPreSerialize(ResourceEvent $event) {
            $event->getData()->setAttribute('custom_field', 'value');
        }
    }
    
  • Register in services.yaml:
    services:
        App\EventSubscriber\CustomResponseSubscriber:
            tags: ['melodiia.event_subscriber']
    

3. Nested Resources

  • Define relationships via #[Resource]:
    #[Resource(
        formType: PostType::class,
        collectionOperations: ['get', 'post'],
        itemOperations: ['get', 'put', 'delete'],
        subresources: ['comments'] // Nested route: /api/posts/{id}/comments
    )]
    class Post {}
    
  • Create a CommentType form and annotate Comment similarly.

4. Authentication/Authorization

  • Use Symfony’s security component:
    # melodiia.yaml
    security:
        enabled: true
        provider: app_user_provider
        roles:
            POST: ROLE_USER
            PUT: ROLE_ADMIN
    
  • Integrate with API tokens or JWT via melodiia.security.firewall.

5. Testing

  • Use Melodiia\Test\ApiTestCase:
    use Melodiia\Test\ApiTestCase;
    
    class PostTest extends ApiTestCase {
        public function testCreatePost() {
            $response = $this->postJson('/api/posts', [
                'title' => 'Test',
                'content' => 'Content',
            ]);
            $this->assertResponseSuccess();
            $this->assertJsonApiResponse($response);
        }
    }
    

6. Upgrading the Persistence Layer (Doctrine ORM 3)

  • 0.12.2 makes ORM 3 a supported target, so you can now upgrade instead of pinning doctrine/orm:^2.
  • Do the two upgrades together — ORM 3 and pagerfanta/doctrine-orm-adapter:^4 — since pagination goes through the adapter:
    composer require doctrine/orm:^3.0 pagerfanta/doctrine-orm-adapter:^4 --with-all-dependencies
    
  • ORM 3 is a major bump: audit any custom repositories, DQL/QueryBuilder calls, and Paginator/Pagerfanta adapter wiring before rolling it out. Melodiia's own adapter support does not shield you from ORM's own removals.
  • If your entities implement Doctrine\ORM\Proxy\Proxy or rely on removed EntityManager methods, fix those first — Melodiia resource endpoints will otherwise fail at hydration time rather than at boot.

Gotchas and Tips

Pitfalls

  1. Form Validation Mismatch

    • Issue: Forms may validate against Default group but API expects api.
    • Fix: Explicitly set validation_groups in formType options (see Implementation Patterns).
  2. CSRF Protection

    • Issue: Forms include CSRF tokens by default, breaking API clients.
    • Fix: Disable CSRF in formType options:
      $builder->setCsrfProtection(false);
      
  3. JSON:API Compliance

    • Issue: Custom attributes may violate JSON:API spec (e.g., nested objects in top-level).
    • Fix: Use setAttribute() for top-level data or nest under data.attributes.
  4. Route Overrides

    • Issue: Auto-generated routes conflict with existing ones.
    • Fix: Disable auto-routing in melodiia.yaml:
      routing:
          auto_generate: false
      
      Then define routes manually in config/routes.yaml.
  5. Pagination

    • Issue: Default pagination may not suit your needs.
    • Fix: Customize via melodiia.yaml:
      pagination:
          enabled: true
          items_per_page: 20
          max_items_per_page: 100
      
  6. Dependency Constraints (0.12.2)

    • Issue: Support for Symfony 8 and Doctrine ORM 3 landed in 0.12.2. On older Melodiia versions these are hard blockers, and Composer will silently keep you on Symfony 7 / ORM 2 until you bump Melodiia.
    • Fix: Pin and verify:
      composer require swag-industries/melodiia:^0.12.2
      composer why-not doctrine/orm 3.0
      
    • Issue: Pagerfanta adapter 4 requires the Pagerfanta 4 line — mixing adapter 4 with older Pagerfanta (or adapter 3 with ORM 3) produces runtime type errors in the paginator, not a Composer conflict.
    • Fix: Upgrade Pagerfanta and the adapter in the same step, then smoke-test every collection endpoint (GET /api/posts?page=2) — pagination is where a broken adapter surfaces first.
  7. Symfony 8 Compatibility

    • Issue: Symfony 8 deprecations surface mostly in form option resolution and event dispatcher signatures. A pre-0.12.2 install on Symfony 8 fails at boot.
    • Fix: On Symfony 8, require Melodiia ^0.12.2; run bin/console debug:container melodiia --show-private to confirm the bundle's services register cleanly after the upgrade.

Debugging Tips

  1. Enable Verbose Logging

    # melodiia.yaml
    debug: true
    

    Logs events to var/log/melodiia.log.

  2. Check Event Dispatching

    • Use Melodiia\Event\ResourceEvent listeners to inspect data before serialization.
  3. Validate JSON:API Responses

    • Use tools like jsonapi-test or manually verify:
      • Top-level data, errors, meta.
      • Relationships use links.related or data arrays.
  4. Isolate ORM 3 Failures from Melodiia Failures

    • When an endpoint 500s after the ORM 3 bump, reproduce the same query in a plain repository test before blaming Melodiia — most regressions land in DQL/custom repositories, not in the serializer.

Extension Points

  1. Custom Serializers

    • Implement Melodiia\Serializer\SerializerInterface and bind in services.yaml:
      services:
          App\Serializer\CustomSerializer:
              tags: ['melodiia.serializer']
      
  2. Dynamic Forms

    • Use FormBuilderInterface callbacks to conditionally add fields:
      $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
          $data = $event->getData();
          if ($data->isAdmin()) {
              $event->getForm()->add('admin_field');
          }
      });
      
  3. Webhook Integration

    • Extend Melodiia\Event\ResourceEvent to trigger webhooks on POST/PUT:
      public function onPostCreate(ResourceEvent $event) {
          if ($event->getOperation() === 'post') {
              $this->webhookClient->send($event->getData());
          }
      }
      
  4. GraphQL-like Queries

    • Use melodiia.yaml to enable partial responses:
      serialization:
          include_nulls: false
          groups: ['api']
      
    • Clients can request specific fields via ?fields[posts]=title,content.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource