Web API: modello REST-ish per l'interrogazione flessibile dei dati delle serie temporali

2

Sto lavorando a un prodotto che espone un'API RESTful per interagire con le entità di sistema (il solito CRUD), che funziona molto bene.

Oltre a CRUD, abbiamo recentemente riscontrato la necessità di esporre la capacità di interrogare dati basati su serie temporali differenti, con filtri diversi e con risoluzioni di aggregazione variabili (ma basate su praticamente le stesse funzioni di aggregazione).

Ad esempio, considera un sistema che gestisce le turbine eoliche. Avresti le solite operazioni CRUD per aggiungere / rimuovere le turbine, ma anche qualche tipo di API per interrogare l'uscita elettrica delle turbine o la velocità di rotazione nel tempo. Potresti voler ottenere una media di queste metriche su tutte le turbine di un sito, o per una singola turbina o per tutte le turbine di un produttore specifico (questi sono i tuoi "filtri"). Potresti volere i dati grezzi (cioè ogni misura eseguita in un determinato periodo di tempo), o punti dati orari, o giornalieri o settimanali (questa è la tua granularità o risoluzione).

Puoi tranquillamente presumere che tutte le query abbiano un filtro orario di inizio / fine e che l'ordinamento sia sempre basato sul tempo.

Il consumatore principale di questi dati è una GUI che rende grafici basati su di esso. È utile, anche se non strettamente necessario, che più metriche siano incapsulate in un singolo endpoint (cioè è possibile ottenere sia la velocità di rotazione della turbina che l'uscita per un punto nel tempo con una singola query).

Ciò che abbiamo fatto storicamente è considerare un tale punto di dati come entità REST (diciamo che chiamiamo TurbineStats ), e abbiamo un endpoint che supportava solo le entità di lista, e accetta i filtri e amp; risoluzione come parametri di query. Ad esempio:

GET /turbine/stats ⏎
    ?start=2018-01-01T10:11:12 ⏎
    &end=2018-01-01T10:11:12 ⏎
    &site_id=1234abcd ⏎
    &model=ABCXYZ ⏎
    &resolution=hourly

[
    {     
         "timestamp": "2018-01-01T11:00:00",
         "rotation_speed": 523.53,
         "output_kwh": 20.5
    },
    {     
         "timestamp": "2018-01-01T12:00:00",
         "rotation_speed": 433.13,
         "output_kwh": 18.5
    },
    {     
         "timestamp": "2018-01-01T13:00:00",
         "rotation_speed": 569.0,
         "output_kwh": 24.1
    },
    ...
]

Questo funziona, ma ci sembra sempre più simile a un anti-pattern, soprattutto perché:

  • Mentre le entità sembrano più o meno uguali e hanno gli stessi campi, i dati possono avere un significato diverso a seconda della query. Ad esempio rotation_speed può essere esatto o mediato
  • Ci sono importanti metadati (come quelli che sono i filtri, quanti punti sono stati considerati, quante turbine sono incluse, ecc.) che possono essere inclusi come parte delle entità ma mescolare dati e metadati è scomodo.
  • Richiedere una singola entità ha poco senso. Questa è fondamentalmente una "sola lista" API
  • Le entità sono calcolate e non hanno identificatori univoci. Possiamo arrivare con l'identificatore calcolato, ma sembra che lo stiamo facendo solo per essere "RESTful" e non per un uso reale.

Puoi dare un esempio di serie storiche che richiedono l'API che funziona bene e si sente ben progettato, RESTful o no? Ci sono dei buoni schemi da guardare?

    
posta shevron 24.07.2018 - 16:07
fonte

1 risposta

1

REST non è perfetto. È essenzialmente focalizzato sull'oggetto e tu crei ed elimini quegli oggetti. Ciò significa che le OPERAZIONI non sono nel punto giusto REST; -)

Prima che REST diventasse popolare, il modo "in" di fare servizi web era SAPONE. Non aveva oggetti, e invece era focalizzata l'OPERAZIONE. Ha gestito magnificamente quello che stai cercando.

La verità è che nessuno dei due metodi funziona molto bene, ma oggi REST è molto in voga, quindi ha senso strutturare i servizi web con questo approccio.

Ma inizia a capire che, per una buona percentuale del tuo design (quanto varia molto da un progetto all'altro), dovrai estendere le definizioni / le migliori pratiche per dare un senso alla tua applicazione.

Ciò che molte persone fanno con REST per affrontare questo problema, è concettualizzare 'oggetti virtuali'. Questi (in genere) non possono essere creati, ma sono in pratica punti di vista o modi per impacchettare le operazioni in modo vagamente un'organizzazione orientata agli oggetti.

Questo è praticamente ciò che hai creato da solo (tranne che quando le persone lo fanno, spesso rendono gli oggetti simili agli oggetti CRUD, non agli oggetti secondari), è l'approccio migliore di cui sono a conoscenza quando utilizzando un modello REST.

    
risposta data 24.07.2018 - 16:45
fonte

Leggi altre domande sui tag