As you noticed, Full Data Path just works. You could make an analogy to system paths, where it would be equivalent to an absolute path.
Data Path is always a fragment of Full Data Path, and so is just there for added convenience (actually both features are there just for convenience). Often you don't need the full path, rather just the part that stays the same, while the rest can change. In case of relative paths in system, you can move a folder to a different place, and the usage of relative paths will keep everything working. In case of Blender, you may want to apply some code to multiple objects:
Copy data path of Viewport Visibility: hide_viewport
and write a loop in console to hide everything:
>>> for o in D.objects:
... o.hide_viewport = True
...
Everything got hidden indeed. Now try to use full data path bpy.data.objects["Cube"].hide_viewport
to unhide everything:
>>> for o in D.objects:
... bpy.data.objects["Cube"].hide_viewport = False
...
Only the cube, from which you extracted the full data path, gets revealed.
When you add a driver and add a variable to it, you specify the block type, block name, and then the Data Path (not Full Data Path) in the field marked red: