Even in Drupal 7, Views had a pretty good integration with the entity system. But seeing as there was no robust entity API to speak of, this integration was not so organic. It required more contributed modules and some custom code to make an entity type work with Views.
In Drupal 8, however, the two are very closely linked and it's a breeze to expose new content entities to Views. If you've followed along with Chapter 7, Your Own Custom Entity and Plugin Types, and have the Product entity type set up, you'll notice that if you try to create a View, you will have no option to make it based on products. That is because, in the entity type definition, we did not specify that it should be exposed to Views. That's all there is to it, actually. We just have to reference a new handler:
"views_data" = "Drupal\views\EntityViewsData"
That's it. Clearing the cache, we are now able to create Views with products that can show any of the fields, can filter and sort by them, and can even render them using view modes. All of these work consistently with the other entity types (at least fundamentally, as we will see in a moment).
You'll notice that we referenced the EntityViewsData data handler which ensures basic logic for entities of all types. If we want to, we can extend this class and add some of our own specificities to the data that is being exposed to Views (or alter the existing ones). This is done inside the getViewsData() method, and we will see an example later on. But if you already want to see an example, check out the NodeViewsData handler for the Node entity type, as it has quite a lot of extra stuff in there. Much of it probably won't make a lot of sense quite yet, so let's slowly get into how Views works by exposing our own custom data to it.