2015-02-06 15 views
7

Utilizzo Spring Data REST 2.1.4.RELEASE.Come si applica una proiezione a una risorsa del metodo di query REST di Spring Data?

ho creato

  • un'entità Booking,
  • suo repository REST (estendendo CrudRepository) denominato BookingRepository
  • e una proiezione BookingDetails (annotato con @Projection(name="details", types = Booking.class)) per la restituzione alcuni dei suoi soggetti legati esploso , ad esempio Resource, Activity, Applicant ecc.

Il client riceve tutte le prenotazioni con .../rest/bookings e la risposta JSON include collegamenti per le entità collegate. Se aggiunge ?projection=details, le entità collegate vengono esplose e restituite. E questo è fantastico.

Ora aggiungo questo metodo personalizzato al repository:

List<Booking> findByApplicant(@Param("applicant") Person applicant); 

Quando il client richiama con .../rest/bookings/search/findByApplicant?applicant=5, sembrano esserci alcun modo per richiedere la proiezione details. A seguito di tentativi vengono ignorati:

  • aggiungendo &projection=details alla stringa di query
  • rendere il metodo restituisce sempre BookingDetails:

    List<BookingDetails> findByApplicant(@Param("applicant") Person applicant); 
    

Riassumendo, metodi di ricerca personalizzati (findBy*) non restituiscono un proiezione. A meno che non annoti il ​​repository con @RepositoryRestResource(excerptProjection = BookingDetails.class), ma questo porta ad alcuni problemi, prima di tutto il client deve sempre utilizzare la stessa proiezione. Come possiamo consentire all'utente di utilizzare le proiezioni anche con i metodi findBy*?

+1

Un URL come '.../rest/bookings/search/findByApplicant? Candidate = 5' non è molto RESTful. Che dire di '.../rest/prenotazioni? Candidato = 5'? –

+1

Anche se non ha nulla a che vedere con la domanda dei poster originali, cosa non ha riguardo a questo URI? Per essere precisi, non si può giudicare la tranquillità di un URI per definizione in quanto dipende unicamente dal fatto che la risorsa esposta attraverso esso segua la semantica HTTP. Se l'id della risorsa è '/ foo' o'/conquer/the/world' è completamente irrilevante. Detto questo, Spring Data REST sfrutta l'ipermedia per consentire ai clienti di navigare verso le risorse in modo che la struttura se gli ID delle risorse diventi anche meno rilevante per nulla :). –

+0

L'URL ha un odore simile a RPC. Ovviamente l'ipermedia è una buona cosa. –

risposta

13

Ho verificato questo funzionamento con Spring Data REST 2.2.1, quindi aggiornarlo. Assicurati che il tuo cliente invii effettivamente i parametri richiesti come desideri. Durante il debug, ho scoperto che ad es. cURL elimina i parametri di query se non si cita esplicitamente l'URI. Quindi questo:

curl http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details 

sarà non inviare nessuno dei parametri di query. Una volta citato l'URI, lo farà.

curl 'http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details' 

Ordina dello stesso è a posto per il sempre più popolare HTTPie. Con esso la sintassi richiesta è:

http :8080/orders/search/findByApplicant applicant==5 projection==details 

Nel caso in cui non si può farlo funzionare in questo modo, sarebbe bello per ottenere un esempio di progetto in esecuzione a guardare.

+2

grazie mille! Mi riempiono di stupidità: l'ho provato con Spring Data REST 2.1.4 alcuni giorni fa e non funzionava; poi ho aggiornato alla 2.2.1 e non ho testato (ho testato solo il nuovo 'excerptProjection'). Ora che collaudo .. vedo che funziona !! Non pensavo che questo potesse essere implementato proprio ora che ne ho bisogno: D Ora correggo la mia domanda. Grazie e scusa per lo spreco di tempo! – bluish

+1

Non preoccuparti. Mi sentivo anche un po 'stupido, non vedendo alcun parametro con un semplice, non quotato 'cURL'. Inoltre, è sempre bene avere queste domande che diventano un riferimento canonico per gli altri che si imbattono nello stesso problema :). Felice che funzioni per te! –

+0

Ciao, mi sono imbattuto in una situazione simile. La soluzione di cui sopra funziona per i metodi di query personalizzati. Ma come aggiungere una proiezione per i metodi incorporati. per esempio, se ho un'entità Ordine,/gli ordini mi daranno tutti gli ordini con la proiezione applicata. Ma quando cerco un singolo ordine usando il link self.href ad esempio/orders/58fa7da00498e41f81a9f806, la proiezione non viene applicata. Come posso ottenerlo? – pvpkiran

Problemi correlati