What is an entity URI? What are entity URIs? What are they used for?

Every answer I see is like Just define in your hook_entity_info() a URI callback. Why, if we are able to define entities and make them work without a custom URI? What is the benefit of the custom URI? Does it bring additional custom, cool functionality to our table that we can exploit?

Some examples of things out there on the web that mention Entity URIs, but don't leave me the wiser: Do entities need to have URIs?, Developing a custom Drupal entity, path(), uri(), defaultUri(), entity_class_uri, what to use?

In a nutshell: Why go through the hassle of defining an entity URI callback in your hook_entity_info(), if you can live without it?
Why go through the hassle of defining an entity URI callback?


To allow other modules to override the entity URI and / or provide a default one.

For instance, I have a student entity defined by the student module. The entity URI is student/%student and is defined from the following hook.

/**
 * Implements hook_entity_info().
 */
function student_entity_info() {
  $return = array(
    'student' =&gt; array(
      'label' =&gt; t('Student'),
      ...
      'uri callback' =&gt; 'student_uri',
      ...
    ),
  );
  return $return;
}

/**
 * Entity uri callback: gives modules a chance to specify a path for a student.
 */
function student_uri($student) {
  return array(
    'path' =&gt; 'student/' . $student-&gt;student_id,
  );
}


Now, let's say I have another module, student_special, which provides a different URI depending on a property in the student object. I can override the URI by implementing hook_entity_info_alter().

/**
 * Implements hook_entity_info_alter().
 */
function student_special_entity_info_alter(&amp;$entity_info) {
  // Add a URI callback to the student entity.
  $entity_info['student']['uri callback'] = 'student_special_uri';
}

/**
 * Entity uri callback: points to a unique URI if the given student is awesome.
 */
function student_special_uri($student) {
  // First look for a return value in the default entity uri callback.
  $default_uri = student_uri($student);

  if ($student-&gt;is_awesome) {
    return array(
      'path' =&gt; 'awesome-student/' . $student-&gt;student_id,
    );
  }
  return $default_uri;
}


We can then use the student URI for a variety of things like creating links or redirecting users to the student entity's view page. For example, if we want to redirect the user to the newly created student after submitting a form.

/**
 * Submit handler for the student create/edit form.
 */
function student_form_submit($form, &amp;$form_state) {

  ...

  // Save the student entity.
  student_save($student);

  // Redirect the user to the student URI.
  $student_uri = entity_uri('student', $student);
  $form_state['redirect'] = $student_uri['path'];
  drupal_set_message(t('Student %title saved.', array('%title' =&gt; entity_label('student', $student))));
}


This ensures that we get the correct URI, especially if there are modules that overrides the default URI.


  Does it bring additional custom, cool functionality to our table that we can exploit?


Alas, there are no lucky charms at the end of the rainbow. Like @googletorp mentions, you still need to define a menu callback for the URI to work, otherwise the URI is just a string that does not map to an existing Drupal menu callback.

There are two ways that you can go about mapping custom Entity URIs to menu callback items: via a standard implementation of hook_menu(), or by overriding the hook_menu() method in your controller, in case you're using Entity API with custom admin ui controllers.