seatplus / eveapi
API for receiving information from esi
Requires
- php: ^8.3
- ext-json: *
- ext-redis: *
- laravel/framework: ^13.0
- laravel/horizon: ^5.0
- seatplus/esi-client: ^4.1
Requires (Dev)
- dg/bypass-finals: ^1.9
- driftingly/rector-laravel: ^2.0
- itsgoingd/clockwork: ^5.0
- larastan/larastan: ^3.0
- laravel/pint: ^1.9
- nunomaduro/collision: ^v8.1
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.1
- pestphp/pest-plugin-type-coverage: ^4.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- rector/rector: ^2.0
- 4.x-dev
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.0
- 3.x-dev
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.x-dev
- 2.1.1
- 2.1.0
- 2.0.0
- 1.x-dev
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
- 0.9.21
- 0.9.20
- 0.9.19
- 0.9.18
- 0.9.17
- 0.9.16
- 0.9.15
- 0.9.14
- 0.9.13
- 0.9.12
- 0.9.11
- 0.9.10
- 0.9.9
- 0.9.8
- 0.9.7
- 0.9.6
- 0.9.5
- 0.9.4
- 0.9.3
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.17
- 0.8.16
- 0.8.15
- 0.8.14
- 0.8.13
- 0.8.12
- 0.8.11
- 0.8.10
- 0.8.9
- 0.8.8
- 0.8.7
- 0.8.6
- 0.8.5
- 0.8.4
- 0.8.3
- 0.8.2
- 0.8.1
- 0.8.0
- 0.7.2
- 0.7.1
- 0.7.0
- 0.6.12
- 0.6.11
- 0.6.10
- 0.6.9
- 0.6.8
- 0.6.7
- 0.6.6
- 0.6.5
- 0.6.4
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.5
- 0.4.4
- 0.4.3
- 0.4.2
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.5
- 0.2.4
- 0.2.3
- 0.2.2
- 0.2.1
- 0.2.0
- 0.1.9
- 0.1.8
- 0.1.7
- 0.1.6
- 0.1.5
- 0.1.4
- 0.1.3
- 0.1.2
- 0.1.1
- 0.1.0
- dev-chore/code-quality
- dev-feat/sde-import
- dev-chore/laravel-13-upgrade
- dev-master
This package is auto-updated.
Last update: 2026-06-02 07:09:07 UTC
README
The EVE Online data-fetching layer for the seatplus platform. Provides queued ESI jobs, Eloquent models for EVE entities, Laravel Horizon integration, SDE import, and reactive character scheduling.
Architecture
eveapi is the second tier of the four-package seatplus monorepo. It has a strict one-way dependency hierarchy:
esi-client (standalone Guzzle HTTP client, RFC 7234 caching)
↓
eveapi ← YOU ARE HERE
↓
auth (EVE OAuth, role system, SSO compliance)
↓
web (Vue 3 + Inertia.js frontend — optional)
Lower packages never import from higher packages.
ESI Data Flow
Queued ESI Job (EsiJob subclass)
│
▼ handle() — injected by container
EsiJob — refreshes token, sets rate-limit context
│ EsiClient (RecordingEsiClient in production)
▼
OPERATION_CLASS::execute($esi, ...) — esi-schema static call
│ EsiResult (typed DTO, isCachedLoad flag)
▼
executeJob() — DB upsert inside a DB::transaction
Recording happens transparently: RecordingEsiClient wraps every invoke() call and stores X-Ratelimit-Remaining + X-ESI-Error-Limit-Remain in Redis for the proactive rate-limit guard.
For full architecture decisions see ARCHITECTURE.md.
Requirements
| Dependency | Version |
|---|---|
| PHP | ^8.3 |
| Laravel | ^13.0 |
| PostgreSQL | 17+ (tests), any for production |
| Redis | 7+ (required for Horizon and rate-limit tracking) |
| seatplus/esi-client | ^4.1 |
| seatplus/esi-schema | ^1.3 (transitive) |
Installation
composer require seatplus/eveapi
Publish and run the migrations:
php artisan migrate
Features
ESI Queue Jobs
All ESI leaf jobs extend EsiJob (ShouldQueue + ShouldBeUnique, 10 tries, exponential backoff). Each job declares the esi-schema resource class it calls via OPERATION_CLASS, and implements tags() and executeJob(). For authenticated endpoints, override getRefreshToken().
Public endpoint example:
final class CharacterInfoJob extends EsiJob { protected const string OPERATION_CLASS = GetCharactersCharacterId::class; public function __construct(public int $character_id) {} public function tags(): array { return ['character', 'info', "character_id:{$this->character_id}"]; } public function executeJob(EsiClient $esi): void { $response = self::OPERATION_CLASS::execute($esi, $this->character_id); if ($response->isCachedLoad) { return; } CharacterInfo::updateOrCreate( ['character_id' => $this->character_id], ['name' => $response->name, ...], ); } }
Authenticated endpoint — additionally override getRefreshToken():
public function getRefreshToken(): RefreshToken { return RefreshToken::findOrFail($this->character_id); }
Paginated endpoint — loop manually using $response->pages:
$page = 1; do { $response = self::OPERATION_CLASS::execute($esi, $this->character_id, $page); if ($response->isCachedLoad) { return; } // ... collect $response->data ... $page++; } while ($page <= $response->pages);
Eloquent Models for EVE Data
| Entity | Models |
|---|---|
| Character | CharacterInfo, CharacterAffiliation, CharacterRole, CorporationHistory |
| Corporation | CorporationInfo, CorporationMemberTracking, CorporationDivision |
| Alliance | AllianceInfo |
| Assets | Asset |
Mail, MailRecipients |
|
| Skills | Skill, SkillQueue |
| Other | RefreshToken, SsoScopes, Schedules, BatchUpdate, BatchStatistic |
Reactive Character Scheduling
CharacterBatchJob self-reschedules character data refreshes based on ESI Cache-Control / Expires headers. When a character's refresh window opens, the job re-queues itself automatically — no cron polling required.
ESI Rate-Limit Tracking
Per-(group, characterId) bucket tracking prevents hitting ESI error limits. Jobs back off transparently when a bucket is close to the limit.
SDE Import
Imports the EVE Static Data Export (universe types, groups, categories, regions, constellations, and solar systems) directly from CCP's FTP:
php artisan seatplus:sde-import
# Or from a local zip (skips download):
php artisan seatplus:sde-import --source=/path/to/sde.zip
The SDE import is also scheduled to run automatically every week.
EVE-Compliant User-Agent
On boot, EveapiServiceProvider sets the EVE-compliant User-Agent header (sourced from seatplus/esi-client's EsiConfiguration) on all outbound Guzzle requests.
Artisan Commands
| Command | Description |
|---|---|
seatplus:sde-import |
Download and import the EVE SDE |
seatplus:check:endpoints |
Verify configured ESI endpoints are reachable |
seatplus:cache:clear [--force] |
Clear the ESI HTTP response cache |
Testing
Tests require a running PostgreSQL instance (seatplus/secret @ 127.0.0.1:5432) and Redis (127.0.0.1:6379).
cd packages/eveapi composer run test # Full suite: lint + types + type-coverage + unit tests composer run test:unit # Pest unit tests only composer run test:lint # Pint formatting check composer run lint # Auto-fix formatting composer run test:types # PHPStan / Larastan static analysis composer run test:type-coverage # 100% type coverage (enforced)
Changelog
Please see CHANGELOG for recent changes.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
License
MIT. Please see LICENSE for details.