How do I find available public methods? I'm finding that the biggest problem in working with Drupal 8 is I can't get the data I need.  Drupal 8 wants me to use public methods rather than manually drilling down thru an object.  The problem is, I can't figure out a consistent way for getting a list of available methods! (they magically exist, and I feel like I'm just supposed to know about them).=

For this example, let's say I have a content type with a video field.  I need to get the raw URL of the video file in that field.

So I'd start with a node id ($nid), and somehow I have to figure out how to load the node.  This isn't too bad because there's lots of examples.  So I do something like $node = \Drupal\node\Entity\Node::load($nid);.

So far so good.  Then I need to get the value of my video field (field_main_video).  This took me FOREVER to figure out because there's conflicting documentation around the 'net.  Finally I figured out I'd have to do something like this (because it is a multivalue item):

$video = \Drupal\node\Entity\Node::load($nid)-&gt;field_main_video-&gt;getValue();


...then loop thru the array etc.  Using kint didn't help me find this, either.  Because, for example, if I kint($node) and look under methods, I don't see getValue() as an item there.  Still not terrible, because there were enough examples around to figure it out.

As I go deeper, though,  what I didn't know (this is the important part) was that rather than getting the video field entity id, then loading the entity, then finding the "uri" field in the entity, etc (like I would in D7):  There was a method that lets me get the URI all in this same line of code!  

$url = \Drupal\node\Entity\Node::load($nid)-&gt;field_main_video-&gt;entity-&gt;getFileUri();


But how could I possibly have known this getFileUri() existed?  I happened to stumble upon it in a blog post.  This truly DOES make getting a URI easier than in D7...but only if you know (magically) what methods exist for each 'level' of an object.

In the end, with this example I'm asking: How do you find all public methods for each level of an object in a way that's easy to read and understand?  Note that it seems there should be a drupal-centric (ie. devel module) way of doing this rather than manually searching api.drupal.org or using something IDE specific?
Content entities are different from most other things in that they often do not have methods and proper interfaces, at least not for configurable fields.

In case of content entities and fields, public methods is not really what you actually want to know, what you want is to know about fields and properties. And only when you get to an entity again through a reference then the methods matter.

For an overview, I always refer to the great Entity API Cheat Sheet.

Content entities have a fixed structure, Entity > Field (FieldItemList) > FieldItem -> Property. A property is either scalar or a reference to something else, e.g. another entity, a language object, a date object, ...

For a few specified examples, some useful snippets:

// List of fields that an entity has, the field definitions also have a lot of information like the type.
array_keys($entity-&gt;getFieldDefinitions())

// Use get() instead of the magic __get() on the entity level then you at least get some type hints.
$entity-&gt;get('field_name').

// Get the list of properties a certain field has, use array_keys() again for just the names, but the definitions also have the type and if it's computed or not.
$entity-&gt;getFieldDefinition('field_name')-&gt;getFieldStorageDefinition()-&gt;getPropertyDefinitions()

// Most field types have value property, but e.g. entity references have target_id and the computed entity. as you found. File and Image fields have additional properties like title/alt/description.
$entity-&gt;get('field_name')-&gt;value
$entity-&gt;get('field_name')-&gt;target_id
$entity-&gt;get('field_name')-&gt;entity

// Note that get('value') is not the same as -&gt;value on the field item level, get() returns a typed data object, get('value')-&gt;getValue() is the same as -&gt;value.

// When not specified, the delta 0 is assumed (all fields are a list internally, even something like the node id), you can use array access or the delta to access another delta, make sure it exists.
$entity-&gt;get('field_name')[1]-&gt;value
$entity-&gt;get('field_name')-&gt;get(1)-&gt;value

// When you have an entity reference, you can get the entity type and class like this:
$entity-&gt;get('field_name')-&gt;entity-&gt;getEntityTypeId()
$entity-&gt;get('field_name')-&gt;entity-&gt;getEntityType()-&gt;getClass()
// or 
get_class($entity-&gt;get('field_name')-&gt;entity)

// From there you can look up the interface and type hint against that, to a) make sure you have a valid, loadable reference and get type hints in an IDE:
$file = $entity-&gt;get('field_name')-&gt;entity;
if ($file instanceof \Drupal\file\FileInterface) {
  $file-&gt;getFileUri();
}