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 Client Laravel Package

realestateconz/api-client

A Laravel/PHP client for the realestate.co.nz API, giving you a clean, fluent wrapper for property listings, search, and related endpoints. Handles authentication, requests, and responses so you can integrate NZ real estate data into your app with minimal boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a thin, vendor-published PHP SDK (0 stars, 0 dependents, not Laravel-specific). There is no service provider, facade, config file, or publishable assets. Treat it as a plain Composer library you wrap yourself — do not expect Laravel ergonomics out of the box.

Install:

composer require realestateconz/api-client

Where to look first:

  1. README.md — for the credential format (API key vs. OAuth client id/secret) and the base URL / environment (sandbox vs. production).
  2. src/ — find the main client class (typically Client or ApiClient) and the request/response layer. This is your source of truth; the README is often stale on a package this small.
  3. composer.json — check the Guzzle major version and the PHP constraint. Old Guzzle pins (5.x/6.x) will fight with a modern Laravel app's dependency graph.

Minimal first use case — pull a page of listings for a region and dump the raw payload so you can see the actual response shape:

use RealestateConz\ApiClient\Client; // confirm exact namespace from src/

$client = new Client([
    'api_key'    => config('services.realestate.key'),
    'api_secret' => config('services.realestate.secret'),
]);

$response = $client->getListings(['region' => 'wellington', 'page' => 1]);
$data = json_decode((string) $response->getBody(), true);
dd($data); // inspect before writing any mapping code

The very first integration task should be an exploratory script like the above. Do not build DTOs or migrations until you have seen a real response body — the client almost certainly returns raw PSR-7 responses rather than typed objects.

Configuration: put REALESTATE_API_KEY / REALESTATE_API_SECRET in .env and expose via config/services.php. Never rely on the package reading env vars itself.

Implementation Patterns

Bind the client as a singleton. The client is stateless HTTP; rebuild it once per request, not per call.

// AppServiceProvider::register()
$this->app->singleton(RealestateClient::class, fn () => new Client([
    'api_key'    => config('services.realestate.key'),
    'api_secret' => config('services.realestate.secret'),
    'timeout'    => 10,
]));

Wrap it in your own service, not the vendor class. Inject RealestateClient into an app-owned PropertySearchService and return your own DTOs/arrays. This is the single most valuable pattern here — it isolates the zero-dependency vendor risk behind an interface you control, so swapping to a hand-rolled Guzzle client later is a one-file change.

Search → paginate → persist as a queued job. Listing APIs are paginated and rate-limited. Model ingestion as a job that requests one page, dispatches itself for page + 1 (with a delay), and upserts by listing ID. Do not loop pages synchronously inside a web request.

$page = $client->getListings(['region' => $region, 'page' => $page]);
// upsert by external id, then dispatch next page with backoff

Upsert, don't insert. Listings change (price, status, sold). Keep a realestate_id unique column and updateOrCreate on it so re-syncs are idempotent.

Cache reads aggressively. Search/browse payloads are a good fit for Cache::remember() with a TTL of minutes, keyed by a hash of the query params. The underlying data changes slowly relative to your read traffic.

Integration tips:

  • Add a Guzzle middleware (via HandlerStack) for request/response logging and retry-on-5xx — the client likely exposes the underlying GuzzleHttp\Client or accepts handler options.
  • Centralize timeout + base URI in config so sandbox and prod differ only by env.
  • If the API supports it, attach an auth token in middleware rather than mutating client state per call.

Gotchas and Tips

No Laravel integration. No auto-discovery, no facade, no config merge. You must register bindings and write config yourself. Do not expect php artisan vendor:publish to do anything.

Vendor/abandonment risk is the real gotcha. Zero stars and zero dependents means no community safety net, no Stack Overflow answers, and a high chance of an unmaintained dependency. Pin the exact version in composer.lock and be prepared to fork. Audit composer.json for stale Guzzle/PHP constraints before adopting on a modern Laravel version.

Raw responses, not DTOs. Expect Psr\Http\Message\ResponseInterface back. You own JSON decoding, key mapping, and error detection — a 200 with an errors key in the body is common in NZ property APIs. Write one parseResponse() helper and use it everywhere.

Auth quirks. If it is OAuth rather than static keys, tokens expire and the client may not refresh them for you. Check whether the token fetch is built in or whether you must supply an access token per request. Refresh on 401, cache the token in your cache store, and never fetch a token per API call.

Rate limits and pagination edge cases. Watch for a total_pages/total_count in the response rather than assuming a full page means "more pages." Add a safety cap on page count so a bug can't spin a queue worker forever.

Debugging: enable Guzzle debug output ('debug' => true in client options) to see the actual request URI and headers. Most "it returns nothing" issues are a wrong base URL or a silently swallowed non-2xx status — check getStatusCode() before decoding.

Testing: bind a fake RealestateClient in tests, or use Guzzle's MockHandler to replay recorded fixture responses. Never hit the live API in CI. Because the client is untested upstream, your own tests around response parsing are your only regression safety.

Extension points: subclass the vendor client to add app-specific helpers, and use Guzzle HandlerStack middleware for cross-cutting concerns (logging, retries, auth headers). Both let you avoid forking while still bending the client to your needs.

Timezones and currency: this is a NZ dataset — store timestamps in Pacific/Auckland at the boundary and convert to UTC in the DB; treat prices as NZD integers (cents or whole dollars — confirm in the payload) to avoid float drift.

Verdict for day-to-day leverage: low. It saves you ~50 lines of Guzzle boilerplate at the cost of an unmaintained, untyped dependency. Use it only if the README's auth flow is genuinely fiddly (signed requests, multi-step OAuth); otherwise a 30-line hand-rolled Guzzle wrapper behind your own interface is lower risk and equally fast.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin