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

Api Component Bundle Laravel Package

silverbackis/api-component-bundle

A Symfony bundle for building modular JSON APIs with reusable components. It helps organize endpoints, handle requests and responses, and keep API code clean, testable, and easy to extend across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Know what you're installing. This is a Symfony/API Platform bundle (components-web-app/api-components-bundle), not a Laravel package. There is no service provider or facade to register. You get value from it in one of two ways:
    1. Run the reference app (Docker/compose) as a components/pattern-library API and consume it from Laravel over HTTP.
    2. Install the bundle into a Symfony + API Platform app and call it from Laravel the same way.
  • Look first at: src/Entity (Component, ComponentGroup, positions/ownership), src/Security/Voter/ComponentVoter.php (authorization rules you'll be fighting), the bundle config for cache/purge settings, and — as of 2.0.0-alpha.30 — tests/Functional/. The Behat features/*.feature files are gone; the PHPUnit functional tests are now the authoritative, executable documentation of every endpoint's behavior.
  • First use case to get working end to end: create a component group → create a component with a position in that group → publish it → GET the rendered/read model → trigger the purge operation → confirm the cache is invalidated. That path exercises ownership, draft/published state, rendering, and the HTTP cache purge in one go.
  • Pin the exact alpha. composer require components-web-app/api-components-bundle:2.0.0-alpha.30 (or run the matching Docker tag). Alphas of this bundle have changed validation semantics between releases; floating constraints will bite you.

Implementation Patterns

  • HTTP-first integration (the Laravel case). Wrap the API in a small client class around Http::baseUrl(...)->withToken(...), not raw Http:: calls scattered through controllers. Map 422 responses to form validation by reading the JSON property paths (component, components, etc.) rather than string-matching messages.
  • Treat drafts and published as one entity for structural rules. The bundle now considers a published component and its draft to be the same node when detecting containment cycles. Mirror that in any client-side tree building you do — don't build a tree from the published view alone and then try to place a draft based on it.
  • Ownership changes go through components. Assigning a group an owner is a relation update on the group, and the new guard rejects it when the owner lives inside the group. Do ownership reassignment as an explicit step in your UX (pick group → pick owner → submit), and surface the components 422 as "that owner is inside this group," not a generic failure.
  • Model the publish → purge pipeline as a queued job. The bundle exposes a rendered-HTML/HTTP cache purge operation; the new functional test for it is the best spec for what gets invalidated. In Laravel, fire a job after a successful publish rather than purging inline — the purge round-trip is the slowest part of the write path.
  • Use the shipped fixtures as seed data. The golden scaffold moved to tests/Functional/Fixture/scaffolds and assets to tests/Functional/assets. Point your local seeding script or your own integration tests at those scaffolds so your fixtures stay shaped like upstream's expectations.
  • Test the contract, not the bundle. Keep your Laravel-side tests on Http::fake() with recorded payloads from the real API; run a thin, nightly integration suite against a running instance. The bundle's own suite is PHPUnit-only now, so if you previously cribbed from the Behat .feature files in CI or docs, rewrite those references against tests/Functional/*Test.php.

Gotchas and Tips

  • Cycle rejection is new and is a behavior change. A position whose component would contain its own group at any depth (published and draft counting as one) now returns 422 on component; giving a group an owner from inside it returns 422 on components. If your client currently posts these and ignores the result, you were silently corrupting the tree before and will now see hard failures. That's the good outcome — but handle both property paths explicitly.
  • The guard is write-side only. ComponentVoter no longer recurses forever on a cycle already in the database — it stops instead of blowing up. If you ran any earlier alpha, audit your tree for pre-existing cycles (a draft/published pair that contains its own group), because nothing will repair that data for you; it will just stop hanging.
  • Behat removal breaks your CI too. Any script, docs link, or copy-paste path referencing features/, features/assets, or features/scaffolds is now dead. New locations: tests/Functional/assets and tests/Functional/Fixture/scaffolds. The Behat-only PHP dependencies are also gone, so behat.yml and its extensions must be dropped.
  • Test environment moved to Symfony 8.1 on the 8.1 legs and is no longer capped at 7.4 by Behat. symfony/yaml and symfony/translation are now direct dev dependencies — if you vendor or fork the test suite, add them explicitly or autoloading/bootstrap will fail in non-obvious places.
  • Both PHPUnit configs fail on Risky. Copying phpunit.xml into your own project means accidental output, missing assertions, or unused mocks fail the build. Useful strictness, surprising first run.
  • In-memory SQLite per process. The functional suite runs each process against its own SQLite database. Great for speed, but it means the upstream suite never proves your Postgres/MySQL-specific assumptions. Run your own integration tests on your real driver before trusting jsonb, collation, or case-sensitivity behavior.
  • Debugging 422s. Log the outgoing payload alongside the response body, not just the status. The property paths (component vs components) point at different layers of the write — one is the position's component, the other is the group's owner relation — and a single form submit can touch both.
  • Extension point worth knowing: custom authorization is expected to compose with ComponentVoter. If you subclass or decorate it, keep your checks iterative rather than recursive over the component tree, for the same reason upstream had to fix their own recursion.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core