kanekescom/laravel-siasn-api
A Laravel wrapper for the SIASN API that simplifies integration with Indonesia's civil service data services. It offers convenient configuration, authentication, and request handling for ASN-related endpoints, helping developers connect Laravel applications to SIASN faster.
Install the package and publish its config:
composer require kanekescom/laravel-siasn-api
php artisan vendor:publish --tag="siasn-api-config" # verify the exact tag in the README
Add credentials to .env (names as documented — typically SIASN_USERNAME, SIASN_PASSWORD, and an API key), then clear cached config:
php artisan config:clear
Where to look first, in order:
config/siasn-api.php — base URL, credentials, timeout, and any token/cache settings. This is the file you will actually touch.Siasn facade class in src/ — as of v2.0.21 it carries method-level annotations, so your IDE will autocomplete the available endpoints. This is the fastest way to discover the API surface without reading the full README.First use case: pull a single ASN record by NIP and dump the response in php artisan tinker:
use Kanekescom\SiasnApi\Facades\Siasn;
$response = Siasn::getDataUtama(nip: '199001012020011001');
dump($response->json());
Confirm you get a success payload before wiring anything into a controller — credential and network issues are the most common first-run failures, and isolating them in tinker saves an hour.
Wrap the facade in your own service. Don't call Siasn:: from controllers or Blade. Create an App\Services\SiasnService that injects or wraps the facade, normalizes the response shape, and throws your own domain exceptions. When the package bumps a version or an endpoint shifts, you have one file to change.
class SiasnService
{
public function asnByNip(string $nip): AsnData
{
$response = Siasn::getDataUtama(nip: $nip);
if ($response->failed()) {
throw new SiasnException("Lookup failed for {$nip}", $response->status());
}
return AsnData::from($response->json('data'));
}
}
Cache aggressively. SIASN reference data (ASN profiles, unit kerja lists, golongan) changes rarely. Wrap reads in Cache::remember() with a TTL matched to your tolerance for staleness — a day is usually fine for profile data, minutes for anything transactional.
Queue bulk operations. Any loop over NIPs must be a job, not a synchronous request. Dispatch per-NIP jobs onto a rate-limited queue so you don't blow through the upstream quota and get your IP or credentials throttled.
Bus::batch($nips->map(fn ($nip) => new SyncAsnProfile($nip)))
->name('siasn-sync')
->onQueue('siasn')
->dispatch();
Use Http::fake() in tests. The package sits on Laravel's HTTP client, so you can fake the upstream without touching the network. Assert on the outgoing request shape (endpoint, headers) and feed fixture JSON back. Keep a handful of real captured payloads in tests/Fixtures/ — SIASN responses are not always shaped the way you'd expect, and faking with your own idealized JSON hides that.
Normalize responses at the boundary. Upstream payloads typically nest data under data and carry their own code/status semantics that may not map cleanly to HTTP status. Map them to a small internal enum inside the service so the rest of your app never parses raw SIASN envelopes.
Log the request ID, not the payload. SIASN responses contain NIP, NIK, and personal data. Log correlation IDs and status codes; keep payload logging behind a debug flag that is off in production.
Siasn facade — purely static-analysis and IDE support. No runtime behavior changed, no action required on upgrade. It does mean your IDE and PHPStan will now resolve Siasn::method() calls properly, so if you've been suppressing "undefined method" warnings on the facade, remove those ignores.php artisan config:cache freezes them. If you rotate SIASN credentials, you must re-run config:cache as part of the deploy. A queued worker that was started before the rotation will keep the old token until restarted — php artisan queue:restart on every credential change.timeout and connect_timeout in config. Default Guzzle timeouts are too long for web requests. Use ->retry(3, 200) on the underlying request for transient 5xx/connection errors only — never retry 4xx.2.0.x patch series on a vendor API wrapper; patch releases have included behavior-adjacent fixes. Pin the version in composer.json ("2.0.21" or "~2.0.21") rather than floating ^2.0, and read the diff before bumping.Http:: calls alongside it — you keep the package's auth, base URL, and error handling instead of reimplementing them.config:cache is stale. That order resolves the large majority of "it just returns nothing" reports.How can I help you explore Laravel packages today?