Along with Drupal 8 release there has been a lot of noise made about headless Drupal with the REST API. Headless Drupal maybe a great choice for data driven use (such as web applications or mobile apps), but for content driven applications (web sites) a pure headless implementation offers little improvement over more traditional site building methods.
When building a content driven website, you're actually using quite a bit of Drupal's features from outside just a simple content repository. These features include block management for layouts and a lot more. With a pure REST API approach you simply miss these altogether.
In addition to just missing features that you're used to - you loose a lot of fundamental functionality of the web. If you're running a site with information on sports activities, you can have URLs like these:
Upon request your backend figures out the required content for the page. On a traditionally built site you'll get error handling automatically, so if you don't have information on floorball - the page will return a 404 status code and a corresponding error page.
If you build your application using a completely separate server application (such as Node.js) not only do you loose the option to use blocks, panels and more but you also lose native support for 404s. You can, for example have an Angular application running with HTML5 History API to remove the hash from the address (http://example.com/sports/football vs http://example.com/#/sports/football).
When you enter your site from the front page (http://example.com/) your Angular application is initialized and will allow you to navigate to the hockey page. Once you enter the hockey page, the address in the field will be "http://example.com/sports/hockey". But if you refresh the page then it might give you a 404 error. Why? Because in the case of a direct reload your browser will make a direct request to the backend for that URL.
If your custom backend does not handle checking if the content exists or not, then you'll likely get 404s, heading to a broken page. You could fix this by always sending a template with the HTTP 200 (OK) message, but that would be breaking the internet. If a page does not exist, it should return a 404.
This gives you more options for mixing and matching various methods, as well as spare you from doing groundlevel work (or worse, breaking the internet).