Data modeling in Drupal - Custom Content Entity

To create data models like in some other platforms you need to use Content Entity.  Drupal org tutorial about this is broken at this point 18/2018 so use this instead
but what you really need is just to use this
where you utilize Drush and generate boilerplate code, then you just add some custom fields around line 150 in your new src/Entity/My_Entity.php file at this line

public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {

defining custom fields is "simple" you just need to add use BaseFieldDefinition::create and define parameters you need. (also note that this are BASE fields,  non-configurable fields that always exist on a given entity type, you can't add or edit them like you do with Field API and UI with nodes)

For example. lets add price as float to our new custom content entity

    $fields['price'] = BaseFieldDefinition::create('float')
     ->setDescription(t('Price of the Currency'))
     ->setDisplayOptions('form', array(
       'type' => 'number',
       'settings' => array(
         'display_label' => TRUE,
    ->setDisplayOptions('view', array(
       'label' => 'hidden',
       'type' => 'number_decimal',
     ->setDisplayConfigurable('form', TRUE)

you can go simpler and add just what you need and leave defaults, for example for storing created date you will have this:

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setDescription(t('The time that the entity was created.'));

By default drupal provides you this field types here…

  • string: A simple string.
  • boolean: A boolean stored as an integer.
  • integer: An integer, with settings for min and max value validation (also provided for decimal and float)
  • decimal: A decimal with configurable precision and scale.
  • float: A float number
  • language: Contains a language code and the language as a computed property
  • timestamp: A Unix timestamp stored as an integer
  • created: A timestamp that uses the current time as a default value.
  • changed: A timestamp that is automatically updated to the current time if the entity is saved.
  • datetime: A date stored as an ISO 8601 string.
  • uri: Contains a URI. The link module also provides a link field type that can include a link title and can point to an internal or external URI/route.
  • uuid: A UUID field that generates a new UUID as the default value.
  • email: An email, with corresponding validation and widgets and formatters.
  • entity_reference: An entity reference with a target_id and a computed entity field property. entity_reference.module provides widgets and formatters when enabled.
  • map: Can contain any number of arbitrary properties, stored as a serialized string

and more....

To get exact types of fields you have on your current installation in devel/php run this to get a list

$widget_types = \Drupal::service('plugin.manager.field.field_type')->getDefinitions();
$plugin_ids = array_keys($widget_types);


you can also do this with console

 drupal debug:plugin field.field_type

and if you need to get list of available widgets do similar

 drupal debug:plugin field.widget

To get formater types, type this to get huge list of them

 drupal debug:plugin field.formatter

Also take a look at link here
where you can find some base field examples you can use.

There is also part of entity_keys in annotations part of this entity declaration file where you have something like:

 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "name",
 *     "uuid" = "uuid",
 *     "uid" = "user_id",
 *     "langcode" = "langcode",
 *     "status" = "status",
 *   },

here you can add key for your new fields like "price" = "price" but this is just an alias and it allows generic code, like the storage backends, to access common fields that have different names, for example the ID.

With those set, all you need to is to install your module now, or if it is already installed then refresh entity definitions with

drupal update:entities

Now you can add your entity with drupal UI, make lists of data with views and utilize all the drupal apis.