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

Laravel Api Model Driver Laravel Package

nazarii-kretovych/laravel-api-model-driver

An Eloquent driver for Laravel that backs models with external APIs instead of a database, so you can query remote HTTP resources while keeping familiar models, relationships, casts, and conventions, without rewriting your data layer.

View on GitHub
Deep Wiki
Context7

Getting Started

This package targets Laravel 7 / PHP 7.2+ and is explicitly a read-oriented bridge: it lets an external REST resource behave like an Eloquent model so you can call familiar methods (find, where, get, relationships) against an API instead of a table. Treat that scope as the contract — it is not a full ORM replacement.

Install and register

composer require nazarii-kretovych/laravel-api-model-driver

Laravel 7 auto-discovers the service provider. If the repo ships a config file, publish it and set the defaults (base URL, timeout, auth) there rather than hard-coding per model:

php artisan vendor:publish --provider="NazariiKretovych\ApiModelDriver\..."

Define your first API model

Create a model that extends the package's base API model (check src/ and the README for the exact base class name — the namespace follows NazariiKretovych\ApiModelDriver). Configure only what the API actually exposes:

class ApiUser extends ApiModel
{
    protected $primaryKey = 'id';
    protected $fillable = ['id', 'name', 'email'];
    protected $casts = ['created_at' => 'datetime'];

    // point at the endpoint, and set auth if needed
    protected $endpoint = 'users';
}

First use case: wrap a read-only third-party resource. The lowest-risk, highest-value entry point is a resource you only ever read — a CRM contacts endpoint, a remote users directory, a status service. You get ApiUser::find(1), ApiUser::where('role', 'admin')->get(), and $user->posts for free, without writing a bespoke client class for every endpoint.

Where to look first

  1. The README examples for the canonical model definition.
  2. The base model class in src/ — this is where the HTTP call is actually made and where attribute mapping happens.
  3. Any config file — timeouts, retries, and auth belong here.

Wire one model against a real sandbox endpoint before building anything on top of it.

Implementation Patterns

Model-per-resource, thin subclasses. Keep API models thin: endpoint, fillable fields, casts, primary key, relationships. Put any transformation logic in accessors or in a dedicated resource/DTO layer so the model stays a faithful map of the remote payload.

Queries as query-string translation. where('status', 'active') typically becomes a ?status=active query param. Confirm how the driver maps operators (where('age', '>', 18), whereIn) against what the remote API supports — only use the subset the API understands, and fall back to client-side filtering with collect() for anything exotic.

Relationships across the boundary. The real payoff is mixing API models and DB models in one graph:

class ApiUser extends ApiModel
{
    public function orders()
    {
        return $this->hasMany(Order::class, 'user_id'); // local DB
    }
}

This works cleanly when the foreign key exists on the local side. The reverse — a DB model hasMany an API model — is where eager loading gets expensive; prefer resolving those lazily and caching.

Cache aggressively behind the model. An API model is a natural place for a read-through cache. Wrap find/get results in Cache::remember keyed by endpoint + query, with a short TTL. This is the single biggest day-to-day win: it turns chatty UI code into something with predictable latency.

Pagination. Expect the driver to surface pagination through the standard Laravel paginator contract. Verify how it reads the remote response's total, page, and per_page fields — many public APIs use different keys, and you may need to override the response-mapping method on the base class.

Auth and headers. Keep tokens in config/env, not in model classes. If the driver exposes a per-request header hook, use it in a base model shared by all your API models so rotation is one change.

Testing. Use Laravel's HTTP fake so tests never hit the network:

Http::fake([
    'api.example.com/users/*' => Http::response(['id' => 1, 'name' => 'Ada'], 200),
]);

$user = ApiUser::find(1);
$this->assertSame('Ada', $user->name);

If the driver doesn't route through the Http facade, check for a swappable client — otherwise tests get brittle.

Gotchas and Tips

Abandoned and version-locked. Last release was 2020-09-23 and it targets Laravel 7. There is no evidence of Laravel 8+ / PHP 8 support. Before adopting, run it against your actual framework version in a scratch app; expect to either pin Laravel 7, fork the package, or vendor the base class into your project. For a 34-star, unmaintained package, vendoring is often the pragmatic choice.

HTTP N+1 is the main performance trap. foreach ($users as $user) { $user->profile; } can become one HTTP request per iteration. with('profile') only helps if the driver implements batched eager loading and the remote API supports filtering by many IDs at once. Check this explicitly — if it doesn't batch, disable lazy loading and load relations in explicit chunks.

Writes are not guaranteed. Do not assume save(), create(), update(), or delete() behave like Eloquent unless the README says so and the remote API supports them. There are no transactions, no rollback, no optimistic locking. Keep write paths in a real client/service class and use this package for reads.

404 vs null. Confirm whether a missing remote record throws ModelNotFoundException or returns null — Eloquent convention is the exception, but HTTP clients often return null. This difference silently breaks findOrFail-style code.

Casting and dates. Remote APIs frequently return strings for booleans, nested objects, or non-ISO dates. Declare $casts and $dates explicitly; don't rely on the driver to guess. Nested payloads need accessors that pull from the raw attribute array.

Timeouts, retries, rate limits. Default HTTP timeouts are often too long for request-path use and too short for slow batch jobs. Set them in config, add retry/backoff for 429/5xx, and respect Retry-After headers. If the remote API rate-limits, a cache is not optional.

Debugging. Log the outgoing URL, method, and status for every request during development — Laravel Telescope or Http::beforeSending/Http::after hooks give you this. Most "the model is broken" issues are actually a wrong endpoint path, a missing auth header, or an unexpected response envelope ({ "data": {...} } vs raw payload).

Extension points to inspect in src/:

  • The method that builds the HTTP request (headers, auth, query string).
  • The method that maps a response array into model attributes — override this if the API wraps data in data.
  • The query builder / grammar that translates where clauses — this is where unsupported operators will fail.
  • Any pagination resolver.

Pin and isolate. If you adopt it, wrap all API models behind a shared abstract base class in your own code, so a future fork or replacement is a one-file change rather than a repo-wide refactor.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib