The preferred way to resolve PubDIDs is in a Datalink service. If the datalink document returned contains one or more rows with #this semantics, the corresponding access URLs are returned, as for pub_did = ivo://org.gavo.dc/~?flashheros/data/taut/f0691.mt ,
As with pub_did = ivo://org.gavo.dc/tap?mlqso/data/slits/BRI0952_data.fits , PubDIDs with a registry part pointing to a TAP service will be looked for in that TAP service's ivoa.obscore table (we don't bother checking if it exists, so this service does not distinguish between a service without obscore and a service with an obscore table that just doesn't have the PubDID in question.
pub_did = ivo://org.gavo.dc/feros/q/ssa?f04031.bdf , is an example for a PubDIDs that has an SSAP service in its registry part. For those, the resolver tries passing in the id through SSAP's PUBDID parameter; if the service isn't broken, that should yield at least one access URL. Note that in the example, two different files are returned, which are representations of the same data set in two formats.
To enable pure data collections or architectures with central, say, datalink services, the resolution process looks at services that the service referenced in the pubDID's registry part declares itself to be served-by. By default, this only happens if the other means of obtaining a result have failed. You can, however, pass force_related = True to go through relationship even in the presence of results.
This is necessary for pub_did = ivo://org.gavo.dc/apo/res/apo/frames?apo/cd/9506/L2237_950602_r_01.fits , as it has an (auxiliary) TAP capabilty itself. When forced to go through the related services, the resolver will hit the TAP service a second time, as the TAP service's main record is in a served-by relationship (as you can see in its resource record