The 'drupal' way to implement delete button UI I think I'm missing something fundamental here. What's the 'right' way to implement a delete button on the UI-end? 

My app has a classic list-type data model: User has wishlist(s) -> wishlist has item(s) -> item has properties. (These are represented in several tables, of course). 

The several views are loaded via tpl files using hook_theme(). When the app has a view loaded for any step of the way (looking at an item in a list, for instance) I want to have edit/delete buttons that act on the item. 
The CRUD methods are in place, they just need to be wired to the button. 

In some places in the app, I've exposed methods via hook_menu(), and that works fine by passing the target to l() - I'm using this for many of my "View Item" UIs. Is there another way, though? This seems to be exposing a ton of core logic to the address bar if I keep going that route. 

In a nutshell: How do I have a button action similar to pseudocode button.click=$this-&gt;bluenose_app_remove_available_property($property-&gt;id);? Preferrably without routing through hook_menu()
What you listed is what we normally do. 

A menu router item (what you define in hook_menu actually serves a lot more than just pointing logical actions to functions/methods. It also makes sure than the items exist, they are accessible, and delivered correctly. 

In hook_menu, you can definite how the access should be granted (with permission system or anything else). You can use wildcard loaders to load items, so you don't have to throw 'page not found' errors yourself. 

You don't have to put your logic in the URLs. If you deal with entities, have your entity build the operation URLs, so they become part of your entity class, and not part of the template (the "View" of traditional MVC). 

When the entity gets complicated, I often end up writing a single menu router to handle them all. The operation argument of a menu path (edit, delete, clone, disable, etc) can be a wildcard loader as well, and you can easily validate it using a method_exists() call.