Which way is the best way will be debatable. If you don't need the actual date of soft delete, then you can just apply/remove a label as necessary:
Mark as "soft deleted":
match (a {name: "foo"}) set a:deleted return a;
Unmark:
match (a {name: "foo"}) remove a:deleted return a;
If you need to assert properties about the soft delete, then it makes sense to model it as a node (e.g. a "soft deletion event") and then link it to the node via a relationship. The nodes that are deleted then are any nodes of a certain type that have a "DELETED" relationship that goes to a soft-delete node. That soft delete node would then have a deleted_at property, along with anything else about the deletion event you're modeling.
I don't think a simple deleted_at
property in the node is as good of a solution, because it confuses the node information with the information about the deletion event. I would argue you're trying to model a deletion event here.