ESI Integration - Incomplete-Infinity/eve-companion GitHub Wiki

🔌 ESI Integration

The EVE Companion App interfaces with the EVE Swagger Interface (ESI) to fetch live data from the EVE Online universe. This page explains how we integrate ESI, generate our own API client, and wrap it within a custom class-based architecture.


🌐 What is ESI?

The EVE Swagger Interface (ESI) is a RESTful API provided by CCP that exposes game data including:

  • Character details
  • Market orders and prices
  • Fleet composition
  • Mail, bookmarks, skills, and more

It is powered by OpenAPI (formerly Swagger), which means we can auto-generate a client with typed interfaces.


🛠️ Generating the Swagger Client

We use [swagger-typescript-api](https://www.npmjs.com/package/swagger-typescript-api) to generate a strongly typed client.

✅ Step-by-step:

  1. Install the generator:
npm install --save-dev swagger-typescript-api
  1. Generate the client:
npx swagger-typescript-api generate \
  --path https://esi.evetech.net/latest/swagger.json \
  --output ./src/api/esi \
  --name index.ts \
  --axios \
  --modular \
  --union-enums
  1. Done! You’ll get typed modules in src/api/esi/ including:
  • apis/ (e.g., CharactersApi, UniverseApi)
  • models/ (interfaces)
  • index.ts (entry point)

📁 File Structure

src/
├── api/
│   └── esi/
│       ├── apis/
│       ├── models/
│       └── index.ts

🔐 Authentication

ESI endpoints often require OAuth2 tokens. We inject tokens like this:

import { Configuration, CharactersApi } from '@/api/esi';

const config = new Configuration({
  basePath: 'https://esi.evetech.net/latest',
  accessToken: token // your bearer token
});

const api = new CharactersApi(config);

🔄 Wrapping Swagger Clients with Classes

We maintain a class-per-file pattern in src/js/main/. Each class wraps a subset of ESI functionality and enriches it with methods, lazy loading, and caching.

Example: InventoryType.js

import { UniverseApi, Configuration } from '@/api/esi';

export default class InventoryType {
  constructor(typeId, token) {
    this.typeId = typeId;
    this.token = token;
    this.name = null;
    this.description = null;
    this.groupId = null;
    this.loaded = false;
  }

  async load() {
    if (this.loaded) return;

    const api = new UniverseApi(new Configuration({
      basePath: 'https://esi.evetech.net/latest',
      accessToken: this.token
    }));

    const { data } = await api.getUniverseTypesTypeId({ typeId: this.typeId });

    this.name = data.name;
    this.description = data.description;
    this.groupId = data.group_id;
    this.loaded = true;
  }
}

This lets us keep custom logic, caching, and transformations inside our own modules, while still relying on the Swagger client for data shape and structure.


💡 Tips

  • Avoid passing raw tokens around. Create a central auth utility to inject them.
  • Group generated API access by characterId, corpId, etc. to simplify wrapper classes.
  • Only load what you need. Use p-queue to throttle ESI calls efficiently.