Progettazione dell'API REST: più risorse e autorizzazioni

3

Sto lavorando su un servizio che inoltra / unifica le nostre chiamate API a piattaforme / servizi esterni.

Ad esempio, diciamo che non voglio gestire tutte le azioni possibili (creare post, recuperare post, modificare post, elencare i post) per Facebook, Twitter, LinkedIn, Google+ a ciascun servizio rivolto all'utente. Pertanto, i servizi rivolti all'utente chiamano questo inoltro API con un messaggio, in qualche modo specifica il servizio da pubblicare a nome e per conto di quale utente proviene la richiesta.

Per inoltrare correttamente la chiamata, devo identificare:

  1. il servizio chiamante, per il quale utilizzo l'intestazione Autorizzazione.

  2. il servizio a cui inoltrare.

  3. l'utente che ha avviato la richiesta. Non dovrei memorizzare le credenziali del servizio esterno dell'utente finale (ad esempio i token di Facebook) nel servizio chiamante ma nel servizio di inoltro.

Ho alcune opzioni su come passare questi dati, e qualsiasi input sarebbe apprezzato:

  1. Specifica il servizio e l'utente come risorse secondarie nell'URL %codice% Per esempio. %codice% Questo mi sembra abbastanza prolisso.

  2. Utilizza i parametri di query. %codice% Per esempio. /service/{externalServiceName}/user/{userReference}/Object/{objectId}

  3. Sovraccarico dell'intestazione Autorizzazione con: %codice% Risultato con URL piacevoli (GET / posts /). Questo sembra totalmente fuori dalle specifiche. Si scopre che specificare più valori per un'intestazione separata da una virgola è nella specifica.

  4. Utilizza intestazioni personalizzate: %codice% Di nuovo, con URL piacevoli e brevi ( GET /service/facebook/user/uid123/posts/post345 ).

  5. Utilizza un mix di intestazioni e risorse personalizzate nell'URL: %codice% Questo ha senso per me perché: 1. il UserReference è in realtà un secondo livello di autorizzazione comunque. 2. Il servizio è la risorsa che possiede l'oggetto. Cioè lo stesso objectId può puntare a risorse diverse in servizi diversi.

  6. Usa JWT per passare il servizio e l'utente, firmato con il segreto del servizio chiamante. /Object/{objectId}?service={externalServiceName}&user={userReference}

Grazie!

    
posta Slav 27.03.2018 - 14:12
fonte

1 risposta

0

Dobbiamo pensare nella migliore API di progettazione a partire dall'obiettivo dell'API.

Il tuo obiettivo API è:

service that forwards/unifies our API calls to external platforms/services

Quindi, inizi con posts endpoint:

POST /posts/

Body
{
    title: "Hello",
    text: "Hello World"
}

Ma questo post può essere pubblicato su Facebook, LinkedIn, ecc. ed è necessario anche il riferimento dell'utente.

È possibile trasmettere queste informazioni sul corpo, ovviamente. Ma:

  • Combina gli attributi esclusivi della piattaforma sullo stesso corpo . Il Twitter, ad esempio, non ha un title o alcune piattaforme hanno il supporto per tags . Questi attributi verranno ignorati per le piattaforme che non li supportano. Il server dovrà capire in fase di esecuzione quale tipo di piattaforma riceve e guardare se ci sono tutti i campi richiesti per quella piattaforma. Il codice potrebbe facilmente essere un disastro.
  • Il cliente gestirà la complessità dell'API . Poiché alcuni attributi sono esclusivi per alcune piattaforme, il client deve controllare quale gruppo di attributi deve inviare per ogni piattaforma per lo stesso stesso .
  • Documentare questa API sarà una cosa difficile da fare . Immagina di mettere un Swagger su questo. Probabilmente il cliente avrà difficoltà a cercare di capire quali informazioni sono supportate per ogni piattaforma.
  • Il supporto per le nuove piattaforme sarà più difficile . Forse vorresti aggiungere una nuova piattaforma che necessita di una nuova informazione da passare insieme al riferimento dell'utente (vedi il mio esempio di Slack).
  • Il controllo delle versioni non è possibile per ogni piattaforma . Non potrai eseguire la versione di ciascuna piattaforma singolarmente, quale potrebbe essere una buona funzionalità per seguire le modifiche di ciascuna piattaforma.

E così via. Puoi pensare in molte possibilità e particolarità di ciascuna piattaforma.

Come puoi vedere, utilizza un endpoint singolo a rischio .

Quindi mi sembra opportuno separarlo in diversi endpoint:

/platforms/facebook/
/platforms/twitter/
/platforms/google-plus/

E l'endpoint URL e body di ciascuno possono avere le sue particolarità. Dividi e conquista.

Puoi capire come /platforms/{platform} , ma fai attenzione. Minaccia questo come generico può portare alcuni problemi se hai bisogno di maggiore flessibilità sull'endpoint URL. Ad esempio, per creare un post su Slack ti servono la piattaforma, l'utente e un canale :

/platforms/slack/users/slav/channels/rest-questions/

Pensando in questo modo, puoi separare le piattaforme e puoi cambiarle tutte senza modificare le altre che stanno funzionando. Anche il GET e altri metodi HTTP sono naturali da usare anche in questo caso.

Informazioni sulla verbosità, non è un problema se ciò apporta chiarezza sull'uso della tua API.

    
risposta data 28.03.2018 - 00:59
fonte

Leggi altre domande sui tag