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

Rest Laravel Package

ibexa/rest

Adds a REST remote API to Ibexa DXP and Ibexa Open Source, letting applications manage content, users, and repositories over HTTP. Useful for building integrations, headless frontends, and third-party clients against Ibexa.

View on GitHub
Deep Wiki
Context7

Getting Started

ibexa/rest is not a client SDK — it is the server-side bundle that exposes the REST API of an Ibexa DXP / Ibexa OSS installation. Day-to-day, a developer either (a) consumes the API from an external app (middleware, SPA, mobile, ERP sync), or (b) extends the API surface for a project. The bundle itself is almost always already installed by ibexa/oss / ibexa/dxp, so "installation" is really a question of verifying it is wired up and reachable.

Minimal steps:

  1. Confirm the bundle is registered and routes exist:
    composer show ibexa/rest
    php bin/console debug:router | grep ibexa.rest
    
    The canonical base path is /api/ibexa/v2/. If you see nothing, the bundle is not enabled in config/bundles.php or the firewall is missing (ibexa.rest firewall, reworked onto Symfony's authenticator system in 5.0).
  2. Read the REST API Reference (https://ezsystems.github.io/ezplatform-rest-reference/) before the source. It is a generated, per-endpoint reference with example request files; the bundle README only points there.
  3. First use case: authenticate and read one content item.
    # 1. create a session
    curl -i -X POST https://example.com/api/ibexa/v2/user/sessions \
      -H "Content-Type: application/vnd.ibexa.api.SessionInput+json" \
      -H "Accept: application/vnd.ibexa.api.Session+json" \
      -d '{"SessionInput":{"login":"admin","password":"publish"}}'
    # capture the session cookie AND the X-CSRF-Token response header
    
    # 2. read content
    curl -i https://example.com/api/ibexa/v2/content/objects/1 \
      -H "Accept: application/vnd.ibexa.api.ContentInfo+json" \
      -b "IBX_SESSIONID=..."
    
  4. Where to look in the code: Server/Router/Resources/config/routing* for the route table, Server/Controller for endpoint behaviour, Server/Output/ValueObjectVisitor for response shapes, and Server/Input/Parser (+ Criterion, SortClause processors) for request shapes. Those four directories answer 90% of "why does my payload look like this" questions.

Realistic first-day scope: session handling + content read + a View (search) query. Creating/publishing content, locations, users/roles and trash operations is a second pass, because each has its own media type and response-code contract.

Implementation Patterns

Session lifecycle is the core pattern. Ibexa REST is cookie/session based, not stateless. A sane integration:

  • Create a session once per worker/process, cache the cookie jar and the X-CSRF-Token header value.
  • Send X-CSRF-Token on every unsafe method (POST/PATCH/PUT/DELETE); its absence is one of the most common 401/403 causes.
  • Detect expiry (401) and re-authenticate once with a lock so N parallel workers do not stampede the login endpoint. v5 also ships a dedicated token-based authentication service if you need a stateless variant, and GET /api/ibexa/v2/user/sessions/current (new in 5.0) lets you probe a session cheaply instead of guessing. Note ibexa.rest.refresh_session is deprecated in favour of ibexa.rest.check_session, and 5.0.8 stopped reusing the auth token after logout — always discard cached credentials on logout.
  • For "which user am I actually acting as" in multi-tenant or impersonation setups, send X-Expected-User (5.0+) so a mismatch fails loudly instead of silently writing as the wrong user.

Always pin the vendor media type. Requests and responses use versioned media types, not plain JSON:

Accept: application/vnd.ibexa.api.Content+json
Content-Type: application/vnd.ibexa.api.ContentUpdate+json

Appending +json selects the JSON visitor; the XML visitor is the historical default in several endpoints. Build a thin client wrapper that sets Accept/Content-Type per operation so callers never hand-write these strings. The supported_media_types flag (5.0.1 / 4.6.23) allows finer media-type granulation — useful if you need to distinguish client generations on the same route.

Content write workflow. The everyday sequence is: create draft → (optionally update draft) → publish, or create with publish folded in. The idiomatic endpoints, and the ones that were explicitly reworked to be OpenAPI-compatible in 5.0 (create draft from current version / from version, publish content version, publish content type, publish role, move/copy/swap location, trash/restore), should be preferred — they have cleaner, spec-matching status codes than the legacy ones. For bulk imports, expect per-item round trips; there is no batch endpoint. Pipeline it, and be aware publishing triggers workflows and URL alias regeneration, so throughput is bound by the domain, not HTTP.

Search via Views. Queries go through POST /api/ibexa/v2/views with a ViewInput containing identifier, public, and a ContentQuery with Criteria, SortClauses, limit, offset. Criterion and sort-clause names come from the input parsers registered in the bundle (ContentTypeIdentifier, FullText, ContentName, ContentTypeGroupName, Image, FileSize, IsBookmarked, …). Two things worth knowing:

  • 5.0.3 prefixed the content-type criterion parsers and exposed a Content Type Search API — old criterion names may not resolve after upgrade; verify names against the reference rather than copying from older blog posts.
  • dataKey (5.0) lets you identify a sort clause from the request, which is the supported way to map inbound sort names to domain sort clauses instead of matching on class name.

Extending the API. For project-specific endpoints:

  • Add a route + controller under Ibexa\Rest\Server\Controller, register as a service, keep the vendor media-type convention so clients use one negotiation path.
  • New response shapes → a ValueObjectVisitor tagged ibexa.rest.output.value_object.visitor.
  • New request shapes → an input parser tagged ibexa.rest.input.parser (the RequestParser interface and its implementations are deprecated since 5.0 — do not build new code on them).
  • New criterion/sort support → extend BaseCriterionProcessor / BaseSortClauseProcessor rather than writing a parser from scratch; this is the intended extension seam introduced in 5.0.

Integration tip: inside the same PHP application, do not call your own REST API. Use the public API repositories (ContentService, LocationService, SearchService). REST is a boundary for remote consumers, and looping through HTTP inside the app doubles latency and adds auth/CSRF failure modes for no benefit.

Gotchas and Tips

  • Media type mismatch is the #1 support ticket. Content-Type: application/json gives you 415; Accept: application/json gives you 406 or an XML body you didn't expect. Diagnose with curl -i and read the Accept-Post/error payload, which usually names the supported types.
  • Don't forget X-CSRF-Token. Session auth without the token produces failures that look like permission problems. Log the token alongside the cookie, and treat both as one credential.
  • 401 vs 404 ambiguity. ACL denials and missing content can look similar; enable the Ibexa debug/profiler and check var/log for the underlying exception. X-Debug-Token in the response will point you at the profiler entry when kernel.debug is on.
  • Binary fields are separate. Image/file field values are not inlined as bytes in the content payload — use the dedicated binary/field endpoints, and note the x-ibexa-example-file header convention (5.0.7) used by the reference example request files when exercising uploads.
  • Response hygiene: ENCODER_CONTEXT leaked into nested objects until 5.0.4 — if you are on an older patch, strip it client-side before persisting API responses into your own store.
  • Redirect loop: redirectCurrentVersionRelations could loop infinitely before 5.0.1 / 4.6.22. If a client hangs on relation redirects, check your patch level first.
  • Version/branch discipline. The 5.x line requires PHP 8.3 and Symfony 7.4 LTS; 4.6.x is the maintenance branch for older stacks. The bundle ships paired releases (e.g. v5.0.8 and v4.6.30 with identical fixes), so pin to the branch matching your Ibexa metapackage and don't mix.
  • Separate firewall. REST lives on its own ibexa.rest firewall with authenticator-manager security (5.0). Project security config that "just works" for the site front end (custom user checkers, SSO listeners) will not automatically apply to API requests — re-verify against /api/ibexa/v2/user/sessions.
  • Browser clients need CORS. Because of the separate firewall, cross-origin calls require explicit CORS config plus credentials; the session cookie plus custom X-CSRF-Token header makes preflight mandatory.
  • Caching: responses are user/permission dependent. Never put a shared reverse proxy in front of authenticated REST calls without Vary on Cookie/Accept and a clear story for the session cookie.
  • Licensing quirk: the package is dual-licensed (Ibexa BUL 2.4 + GPLv2) and NOASSERTION in metadata. If you are redistributing or building a product on top, get the actual license text from Ibexa rather than trusting the repo metadata — and note the GPL branch is what you get without a DXP subscription.
  • Small ecosystem: 5 stars, 0 dependents. Expect to read the source and the generated reference rather than finding community answers; budget time for that on your first custom endpoint, and prefer the extension seams (BaseCriterionProcessor, BaseSortClauseProcessor, tagged visitors/parsers) over monkey-patching controllers, so future 5.x upgrades stay cheap.
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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc