Salta al contenuto

App mobile e web

App di spotting, avvisi di voli insoliti, mappe: la chiave resta sul tuo server e l’app chiede a te. Così il consumo dipende da quanto spesso aggiorni, non da quanti utenti hai.

Lo schema

Il tuo server scarica i dati a intervalli fissi e li tiene in memoria; l’app chiede al server solo quello che le serve. Puoi scaricare una zona per ogni area che servi, oppure, da Pro in su, il mondo intero in una richiesta.

La tua app
chiede al tuo server, senza chiave
Il tuo server
cache in memoria, aggiornata ogni 30 s
API FlyItalyADSB
la chiave sta solo qui

Quanto consuma

Con la cache il conto non dipende dagli utenti. Due esempi, con un aggiornamento ogni 30 secondi:

SchemaAl mesePiano
Il mondo intero in una richiesta86.400Pro (solo Pro e Fleet hanno il raggio mondiale)
10 zone da 500 km864.000Starter (fino a 1.000 km e 1 milione al mese)
Ogni utente chiede all’API da sé, 1.000 utenti attivi86.400.000oltre i piani self-service: da evitare

Il mondo intero pesa circa 7,2 MB di JSON, 1,1 MB con gzip: non ci sono limiti di banda, contano solo le richieste. Chiedi la compressione (Accept-Encoding: gzip, fetch lo fa da sé).

Il codice

Il tuo server, una cache per tutti (Node 18+)
// server.mjs: una cache per tutti gli utenti della tua app (Node 18+, nessuna dipendenza)
import http from 'node:http';

const KEY = process.env.FIA_API_KEY;
// Pro e Fleet: il mondo intero. Con Free usa la tua zona (fino a 500 km).
const SOURCE = 'https://api.flyitalyadsb.com/v2/lat/0/lon/0/dist/20000';
const ATTRIBUTION = 'Dati di volo: FlyItalyADSB (flyitalyadsb.com), CC BY-SA 4.0';
let snapshot = { now: 0, ac: [] };

async function refresh() {
  try {
    const r = await fetch(SOURCE, { headers: { 'X-Api-Key': KEY, 'User-Agent': 'my-app-backend/1.0' } });
    if (r.ok) snapshot = await r.json(); // fetch decomprime il gzip da solo
    else console.log('refresh', r.status, r.headers.get('retry-after') ?? '');
  } catch (e) {
    console.log('refresh failed', e.message); // resta l’ultima copia
  }
}
refresh();
setInterval(refresh, 30_000);

const km = (la1, lo1, la2, lo2) => {
  const p = Math.PI / 180;
  const h = Math.sin(((la2 - la1) * p) / 2) ** 2
    + Math.cos(la1 * p) * Math.cos(la2 * p) * Math.sin(((lo2 - lo1) * p) / 2) ** 2;
  return 12742 * Math.asin(Math.sqrt(h));
};

// GET /near?lat=40.64&lon=-73.78&km=25
http.createServer((req, res) => {
  const q = new URL(req.url, 'http://localhost').searchParams;
  const lat = Number(q.get('lat')), lon = Number(q.get('lon'));
  const radius = Math.min(Number(q.get('km')) || 25, 250);
  const ac = snapshot.ac.filter((a) => a.lat != null && km(lat, lon, a.lat, a.lon) <= radius);
  res.writeHead(200, { 'Content-Type': 'application/json', 'Cache-Control': 'max-age=5' });
  res.end(JSON.stringify({ now: snapshot.now, attribution: ATTRIBUTION, ac }));
}).listen(8080);
Nell’app
// Nell’app: chiedi al tuo server, mai all’API con la chiave
const res = await fetch('https://tuo-server.example/near?lat=40.64&lon=-73.78&km=25');
const { ac, attribution } = await res.json();
// mostra «attribution» dove l’utente vede gli aerei

Al posto di LA_TUA_CHIAVE la tua chiave: è gratuita, si chiede qui. Specifica completa in openapi.json. Esempi completi (curl, Python, Node.js e un display ESP32 da scrivania) su GitHub.

Funzioni in più per un’app

  • Storico: la traccia di un aereo in un giorno, anche oggi, con /v2/history/{hex}/{data}. Storico.
  • Sorvoli: gli aerei passati sopra un punto tra due istanti, con /v2/overflights.
  • Emergenze e aerei particolari: squawk di emergenza, militari e altri aerei particolari in una zona con /v2/events, e con i piani a pagamento gli stessi eventi in push sul tuo URL. Avvisi e webhook.
  • Profilo di un aereo in una richiesta: identità, se lo vediamo ora, primo e ultimo giorno nello storico, con /v2/profile/{hex}.

Un’app che lo fa già

Prodotti costruiti sui dati della rete, mostrati con il permesso di chi li fa.

App mobile · piano Pro

FlyScoutdi Apptractor

Trova i voli insoliti in tutto il mondo, come riattaccate, attese, emergenze e aerocisterne in circuito, e li fa rivedere su una mappa.

Come usa i datiIl server di FlyScout legge il mondo intero dalla nostra API e ne ricava gli eventi; l’app parla solo con quel server.

“Really happy I switched to your service.”

Stan, Apptractor · Citazione originale, in inglese.

Hai costruito qualcosa sui dati di FlyItalyADSB? Scrivici: se ti va, lo aggiungiamo qui.

Attenzione a

  • Mai la chiave nell’app o nella pagina web. Il CORS è aperto, ma una chiave nel codice del client la vede chiunque.
  • Aggiornare più spesso di ogni mezzo secondo non serve: il dato non cambia più velocemente.
  • L’attribuzione nell’app, dove l’utente vede gli aerei: la riga da usare. Il server dell’esempio la restituisce insieme ai dati.
  • Su un 429 tieni l’ultima copia e riprova dopo Retry-After: gli utenti non se ne accorgono.
  • Non ci sono tratte né foto nei dati: se l’app mostra partenza e arrivo, serve un’altra fonte.

Per approfondire

← Per chi costruisce prodotti