Parece que es mejor escribir un controlador personalizado en lugar de usar Spring Data REST aquí, ya que básicamente necesita dos recursos:uno para agregar un enlace o devolver uno existente y otro para recuperar un URI original a través de su hash.
En el primer método, simplemente llamaría a un método de repositorio findByLongURL(…)
y use la URL
obtenida instancia si tiene un resultado o da un segundo paso para crear realmente el hash y guardar la URL
repositorio de pensamientos de instancia. El segundo recurso básicamente lo llamaría método ya existente.
Eso es sencillo y fácil de digerir.
Si necesita que la implementación del método anterior sea una operación atómica, el método de consulta del repositorio debe implementarse manualmente (para obtener instrucciones generales al respecto, lea la sección correspondiente en documentación de referencia ):
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);
}
}
Como puede ver, esto implica tratar con algunos detalles de nivel inferior (aunque la verbosidad se puede reducir mediante el uso de importaciones estáticas), pero básicamente le brinda una operación atómica.