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

Melodiia Laravel Package

biig/melodiia

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require swag-industries/melodiia
    

    This auto-generates melodiia.yaml in config/.

  2. 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).
  3. 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.

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);
        }
    }
    

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
      

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.

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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui