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

Non Eloquent Laravel Package

laravel-json-api/non-eloquent

Laravel JSON:API adapter for non-Eloquent data sources, letting you expose custom repositories or external APIs through the JSON:API spec with resources, relationships, filtering, sorting, and pagination—no Eloquent models required.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is an extension, not a standalone library — it plugs into an existing laravel-json-api/json-api installation and adds an adapter path for non-Eloquent data. Architecturally it is a thin adapter: the abstract Schema class doubles as schema and storage contract, so the integration surface is a small set of method signatures (all(), find(), optionally create()/update()/delete()) plus field resolvers. That shape is favorable — it keeps persistence in a repository/service layer and leaves the API layer as a declarative shell. It fits cleanly when JSON:API is already the house standard and a minority of resources have no table behind them (aggregations, reporting views, cached DTOs, integration payloads, feature flags). It is a poor fit if most resources would be non-Eloquent — that is a sign the architecture is wrong, not something to patch.

Integration feasibility. Low mechanical cost. composer require, extend the base schema, register in Server::allResources() alongside Eloquent schemas, implement only the storage methods you need, and routes work as usual (JsonApiRoute::server('v1')->resources()->all()). Filters, sorts, pagination, sparse fieldsets, includes, and query-parameter validation are inherited from the parent — the entire point of the package is conformance, not novelty. The prerequisite is non-negotiable: a working parent install, a registered Server, and at least one green Eloquent-backed resource before you start, otherwise you cannot distinguish a broken adapter from a broken baseline. A time-boxed afternoon spike is realistic.

Technical risk. The dominant risk is maturity, not code. Four stars and zero known dependents means you are the compatibility test suite. Specific hazards:

  • Version matrix. The package tracks a specific laravel-json-api/* major; PHP, Laravel, and parent constraints must all line up. A mismatch is a fork decision, not a workaround.
  • ID ownership. Eloquent supplies a stable primary key; a DTO does not. Null, array-shaped, or unstable IDs break linkage, find(), and includes in ways that surface far from the cause.
  • Authorization is not inherited. Eloquent resources get model-layer scoping and policies. Non-Eloquent resources bypass all of it unless wired explicitly. This is the primary security exposure of adopting the pattern.
  • No lazy loading. An include over a remote source fans out into a call per parent unless the repository preloads in bulk.
  • Upstream failures have no default semantics. A timeout, 5xx, or partial payload must become a deliberate JSON:API error — not a 500 with a stack trace.
  • Sparse fieldsets change what executes, so required side effects must not live in resolvers.

Key questions to answer before committing:

  1. Which specific endpoints are non-Eloquent, and are they read-only or writable? The clearest first case is read-only reference data (all()/find() only).
  2. What is the backing source, and what is its realistic latency and failure rate?
  3. Does any non-Eloquent resource need a relationship to a real Eloquent model? This is the highest-value and highest-risk pattern; spike it explicitly.
  4. Who is the named owner of the package and the fork? Is a fork budgeted as a plausible outcome?
  5. How is authorization enforced per endpoint — in the repository, the request's authorize(), or a scoping hook?
  6. What is the version-pin policy for both this package and the parent?

Integration Approach

Stack fit. Laravel + laravel-json-api in production, JSON:API as the documented contract, and an API surface that is predominantly Eloquent-backed. Where those hold, the fit is clean because everything above the storage layer is unchanged — the day-to-day configuration you already do (filters, sorts, pagination, request validation) carries over verbatim.

Migration path. Incremental, resource-by-resource. The package directly replaces the fake-model anti-pattern (wrapping an external call in a stub Eloquent model, which creates invisible coupling and query-builder paths that never execute) and it decouples reporting, dashboard, and integration endpoints from schema/database workstreams — a delivery-date decision as much as a technical one. It also supports moving a legacy surface to JSON:API without a big-bang rewrite gated on data-layer work.

Compatibility. Read the vendored composer.json and pin both packages explicitly. The vendored Schema.php abstract method signatures are the contract — they override anything found online. Treat the package as a small vendored utility: budget an afternoon to read it fully and be able to fork it. It is a few hundred lines of thin adapter.

Sequencing.

  1. Establish the baseline: parent package configured, Server registered, one Eloquent resource returning a correct JSON:API document.
  2. Read the vendored source end to end — abstract Schema, the Store contract, the README version matrix.
  3. Feature-flag the rollout: register the non-Eloquent schema on its own Server or route group so you can A/B the response shape without disturbing Eloquent resources.
  4. Ship the first use case read-only: a reference resource (countries, currencies, categories, feature flags, or a cached external payload) implementing only all() and find(). This exercises routing, serialization, includes, fieldsets, and pagination without touching writes.
  5. Spike the hard cases: a paginated external-API-backed collection, and a resource with a to-many relationship to a real Eloquent model.
  6. Add writes only if needed, as thin delegators to a service, paired with standard JsonApiRequest classes. Business rules stay out of schemas.
  7. Promote from the flagged route once contract tests (assertions on the serialized JSON:API document — type, id, attributes, relationships, links, meta) are green.

Design rule to enforce in review. Wrap a repository, not an array. Keep persistence and fetch logic in a service the app already uses, so the backing source (static array → Redis → API) can change without touching the API layer — and so each schema can be reimplemented as a custom adapter if the package stalls.

Operational Impact

Maintenance. Low code volume, low churn, but you are the maintenance plan. Pin versions, assign a named owner watching upstream, and budget a small internal fork or wrapper as a plausible outcome rather than a disaster. Keep schemas thin and repositories thick so the exit path stays cheap: if the package stalls, each schema becomes a custom adapter over the same repository and day-to-day code does not move.

Support. No vendor SLA, no community body of answers, no dependents to learn from. The safety net is contract tests plus an internal owner. Do not make it a critical-path dependency without that owner named.

Scaling. Treat the upstream as slow by default. Batch aggressively at the repository layer: preload related records in bulk for includes, cache the result of all(), and assume every include is a fan-out unless proven otherwise. Do not put expensive computation in resolvers — sparse fieldsets mean they may never run, and when they do run it is per-record.

Failure modes to design and test for:

  • Upstream timeout, 5xx, or partial payload surfacing as a 500 instead of a JSON:API error object.
  • Unstable or null IDs breaking linkage, find(), and includes.
  • Missing or wrong-typed value resolvers producing silently blank attributes or mid-serialization type errors.
  • Authorization gaps — data leakage on endpoints that bypassed model-layer scoping.
  • Version drift between this package, the parent, and the framework.
  • Hand-rolled filtering/sorting that diverges from parent validation and error semantics.

Ramp-up. The adapter surface is tiny; most bugs live in your resolvers and your IDs, so give the team an explicit debugging order: confirm the schema is registered in allResources(), confirm find() returns the expected object, confirm each resolver returns the expected type, inspect the raw response for id/type linkage, and only then look at the parent package's serialization. That sequence, plus the "read the vendored source first" habit, is the whole onboarding curve — roughly a day for a competent Laravel developer, plus the spike time on relationships and external pagination.

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