Het voelt alsof je beter een aangepaste controller kunt schrijven in plaats van Spring Data REST hier te gebruiken, omdat je in feite twee bronnen nodig hebt:een om een link toe te voegen of een bestaande te retourneren en een tweede om een originele URI via de hash op te halen.
In de eerste methode zou je gewoon een repository-methode findByLongURL(…)
aanroepen en gebruik de verkregen URL
bijvoorbeeld als je een resultaat hebt of een tweede stap zet om de hash daadwerkelijk te maken en de URL
op te slaan bijvoorbeeld gedachten repository. De tweede bron zou in feite gewoon je reeds bestaande methode noemen.
Dat is ongecompliceerd en gemakkelijk te verteren.
Als de implementatie van de eerste methode een atomaire bewerking moet zijn, moet de querymethode voor de repository handmatig worden geïmplementeerd (voor algemene instructies hierover lees de relevante sectie in de referentiedocumentatie ):
class UrlRepositoryImpl implements UrlRepositoryCustom {
private final MongoOperations operations;
public UrlRepositoryImpl(MongoOperations operations) {
this.operations = operations;
}
@Override
public URL findOrInsert(String source) {
// What to find?
Query query = Query.query(Criteria.where("longURL").is(source);
// What to write if nothing can be found
Update update = new Update()
.setOnInsert("longURL", source)
.setOnInsert("hash", calculatedHash);
FindAndModifyOptions options = new FindAndModifyOptions.options()
.returnNew(true) // returns the document insert (if so)
.upsert(true); // insert document if it doesn't exist
return operations.findAndModify(query, update, options, URL.class);
}
}
Zoals je kunt zien, omvat dit het omgaan met details op een lager niveau (hoewel de breedsprakigheid kan worden verminderd door statische importen te gebruiken), maar het geeft je in feite een atomaire bewerking.