seatplus/eveapi
A Laravel package for integrating EVE Online's ESI API into Seatplus applications. It offers API client tooling, authentication and token handling, plus convenient access to character, corporation, and alliance data for building EVE-related features.
Install the package and let it wire itself into the container:
composer require seatplus/eveapi
php artisan vendor:publish --tag=eveapi-config # config/eveapi.php
php artisan vendor:publish --tag=eveapi-migrations
php artisan migrate
Then set the ESI application credentials in .env (EVE_CLIENT_ID, EVE_CLIENT_SECRET, EVE_CALLBACK_URL — confirm exact keys in the published config/eveapi.php; the service provider reads them at boot, so php artisan config:cache afterwards).
Where to look first:
config/eveapi.php — client credentials, scopes, model/table overrides, cache and queue settings.src/Models/ — CharacterInfo and friends (Corporation, Alliance, token models). This is the layer you will query in your app.src/ service bindings + routes — check php artisan route:list | grep -i eve to see whether the package registered its SSO callback for you or expects you to define one.src/Jobs / console commands — the shipped token-refresh and sync jobs you can schedule rather than reinvent.First use case: add a character via EVE SSO, persist the refresh token, then read $character->corporation / $character->alliance in a controller. Do that end-to-end before writing any sync logic — it validates credentials, scopes, callback URL and migrations in one pass.
Token lifecycle is the core abstraction. Almost everything else is downstream of having a valid access token per character. Drive it through the package's refresh token model/service rather than storing raw tokens yourself; treat a 400 invalid_grant from the token endpoint as "this character needs re-authentication" and mark the record accordingly instead of retrying.
Wrap ESI access in your own service/job layer. Don't call endpoints from controllers. A thin EsiService/FetchCharacterAssets job that depends on the package client keeps you insulated from endpoint changes and gives you one place to add logging, retries and rate limiting.
Fan out per character, queue it, and constrain it.
SyncCharacterAssets::dispatch($character)
->onQueue('esi')
->middleware([WithoutOverlapping::class]);
Use WithoutOverlapping keyed on character_id, plus a Redis-backed throttle, so a hundred-character corp doesn't trip ESI's error budget.
Respect caching headers. ESI GET responses carry Expires; cache the parsed result with that TTL (Cache::remember($key, $ttl, ...)) rather than a hardcoded 60s. ETag/If-None-Match support is worth wiring if you poll the same endpoints often.
Pagination: iterate ?page=N until an empty array is returned. Not every endpoint returns X-Pages, so don't gate your loop on that header alone.
Extending models (relevant to 5.1.1): if you subclass a package model, declare the parent explicitly so static analysis and consuming packages resolve it:
/** @extends \Seatplus\Eveapi\Models\Character\CharacterInfo */
class Character extends CharacterInfo {}
Then either point the package's model config at your subclass or keep a separate Eloquent model with a belongsTo back to the package model — pick one and stick to it, because the package's relations will still return its own classes.
Testing: fake at the HTTP layer (Http::fake([...])) rather than mocking the package client, so your code exercises the real parsing/normalisation. Use RefreshDatabase and remember the package migrations ship fixtures you probably don't want in tests — verify what gets seeded.
Events as an integration seam: hook the package's character-added / token-refreshed events to trigger your own downstream syncs instead of polling for new rows.
retry(3) around ESI calls.migrate in production. Publish, diff, then migrate.@phpstan-ignore, @mixin, or hand-written stubs to work around unresolved model types when extending package models, remove them, upgrade, and re-run Larastan/PHPStan plus barryvdh/laravel-ide-helper:models. No breaking changes are expected from 5.1.0 — it's a patch, so composer update seatplus/eveapi and clear caches is the whole migration..env without config:clear is the #1 cause of "it works in tinker but not in the app".How can I help you explore Laravel packages today?