Best practice: Twig logic versus Preprocess functions
Best practice is documented in the node template. These are the two most important variables:
* Available variables:
 * - node: The node entity with limited access to object properties and methods.
 *   Only method names starting with &quot;get&quot;, &quot;has&quot;, or &quot;is&quot; and a few common
 *   methods such as &quot;id&quot;, &quot;label&quot;, and &quot;bundle&quot; are available. For example:
 *   - node.getCreatedTime() will return the node creation timestamp.
 *   - node.hasField('field_example') returns TRUE if the node bundle includes
 *     field_example. (This does not indicate the presence of a value in this
 *     field.)
 *   - node.isPublished() will return whether the node is published or not.
 *   Calling other methods, such as node.delete(), will result in an exception.
 *   See \Drupal\node\Entity\Node for a full list of public properties and
 *   methods for the node object.
 * - label: (optional) The title of the node.
 * - content: All node items. Use {{ content }} to print them all,
 *   or print a subset such as {{ content.field_example }}. Use
 *   {{ content|without('field_example') }} to temporarily suppress the printing
 *   of a given child element.

It clearly states that you should print the render array {{ content }} and use the object {{ node }} with its properties and methods to get the node data you need.