Come utilizzare API RESTful esterne con Symfony?

9

Stiamo costruendo un'architettura Microservice per i nostri progetti, con applicazioni Symfony principalmente front-end che interagiscono con le API RESTful back-end.

Il problema è che questo approccio sta infrangendo la gestione delle entità di Symfony affidandosi a Doctrine con il database. Dove Symfony solitamente gestisce entità con Doctrine, automatizzando gran parte del lavoro, questo non può essere riprodotto facilmente quando dobbiamo accedere a dati esterni dalle API.

Ad esempio, con un'entità Client:

  • Usando Doctrine, dobbiamo solo definire la nostra classe Client, ed ora è facile creare, aggiornare, recuperare i nostri clienti
  • Utilizzando l'approccio dell'API REST, i client sono accessibili tramite l'API, ma abbiamo molto lavoro per definire come viene creato il client (POST), aggiornato (PUT), recuperato (GET), ecc.

Da notare che i client sono utilizzati da diverse applicazioni, non solo l'app front-end, quindi l'API dedicata.

Dovremmo creare classi con metodi simili all'entità nascondendo la complessità delle chiamate API, importando localmente tutti i dati API e accedendoli tramite Doctrine, o in qualsiasi altro modo?

    
posta Pierre B. 14.10.2016 - 12:41
fonte

2 risposte

2

Ho realizzato un progetto basato su symfony che usa un'API esterna (JSON); quello che ho fatto è stato creare una libreria client indipendente ("client library" - una parte di software, pacchetto di compositore), con il proprio set di entità (POPO); si integra con il framework utilizzando le interfacce fornite da Symfony (ad esempio, creando semplicemente un provider utente personalizzato ) .

Il client effettua chiamate http "dietro le quinte" - questo è importante per le funzionalità di test future. Non vuoi esporre il tuo modo di comunicare con la tua fonte di dati e inoltre non vuoi che i tuoi test facciano affidamento su live API.

Interfaccia della libreria client (ad esempio come potrebbe essere):

class ApiClient {

   /**
    * @throws SomeApiException If credentials are invalid
    * @return ApiUser
    */
   public function authenticate($username, $password);

   /**
    * @return ApiUser
    */
   public function findUserByEmail($email);

   /**
    * @throws SomeApiException If email is invalid
    * @return void
    */
   public function changeUserEmail(User $user, $newEmail);
}

La libreria client utilizza internamente Guzzle per la comunicazione e il componente Doctrine Cache per il caching dei risultati. La mappatura tra oggetti entità e json è stata effettuata dai mappatori, che una volta scritti non sono cambiati molto spesso (o eventi). In questo caso, suggerirei di usare JMS Serializer per una trasformazione automatica da e verso JSON (presumo che tu usi JSON).

Avrai bisogno di un buon meccanismo di memorizzazione nella cache e di una memoria locale, come Redis. Effettuare chiamate API su ogni richiesta di app ucciderà il server e rallenterà drasticamente l'applicazione. È molto importante capire come funzionano le cache http. Se la tua API non usa le intestazioni di cache (o la usa in modo oscuro) sarà molto difficile e dispendioso in termini di risorse per tenere traccia delle modifiche.

Dovresti anche pensare a come dovrebbe comportarsi il client se la connessione si interrompe, se il client usa dati in stallo? Sarebbe una buona idea utilizzare un server proxy tra la tua app e l'API. In questo caso il proxy (come Varnish) potrebbe velocizzare le tue richieste e anche aggiornare i dati in stallo in background senza rallentare la tua app. Mantiene anche il tuo sito Web online in caso di errore API. Potresti non essere in grado di scrivere dati nel frattempo, ma i tuoi utenti potranno comunque consultare i dati memorizzati nella cache.

E a proposito di Doctrine, consulta la " Legge dello strumento ".

    
risposta data 26.02.2017 - 03:57
fonte
1

Doctrine è un livello di accesso al database. Non vuoi accedere a un database, ma a un apis. Puoi ancora creare un'entità, ma come un semplice oggetto che non deve estendere nulla al nostro strumento (un popo). Dovrebbe avere un repository che implementa tutti i metodi CRUD. In questo caso chiama l'API al posto del database. Creerei un'interfaccia per quello. Non deve essere diverso per l'applicazione da utilizzare, tranne che devi tener conto ovunque che un micro servizio potrebbe non rispondere.

    
risposta data 22.10.2016 - 11:45
fonte

Leggi altre domande sui tag