It's been a while since I've sat down and tried to write a module from scratch in Drupal 8. I've dabbled here and there in the various already existing modules but there's always something interesting about just trying to write that simple "Hello World" module. Sure, starting from scratch isn't really something we do all that often, but it's nice to to know how it works.
So, as part of our Learning Drupal 8 by Trial and Error blog posts, I set out to write what is probably one of the simplest tasks you could want to do with a custom module. Displaying the text "Hello World" as the primary content of the page. In the process of doing so I learned that while the general concepts are much the same as Drupal 7 — you're simply finding a way to map a URL to some PHP code that gets executed — the mechanics of it are much different in Drupal 8.
Most of the information I used while doing this was found by searching through the change records on drupal.org which provide a list and some basic documentation for most of the big changes between Drupal 7 & 8.
.info files and YAML
First up was the .info file. Which in Drupal 8 is now really a modulename.info.yml YAML file. Asside from the sytax differences between the old .ini style files and the new YAML files things are mostly the same here. Give your module a name, a description, and some other basic metadata that Drupal needs. I mostly read through these examples and looked at the .info.yml files of a few core modules for reference.
Symfony 2 routing
The other big thing for me that I knew existed, but hadn't encountered up until this point, is the new Symfony 2 based routing system. It's basically Drupal 8's version of the routing portion of what hook_menu() in prior versions did. The hook_menu() hook still exists, but it's now exclusively used for defining menu items, not menu items and their routes. You can read more about modulename.routing.yml files and how they work. At the end of the day though you're still just mapping a URL to some PHP that gets executed.
Also worth mentioning is the PSR-0 naming standard which is being used by Drupal 8 to perform autoloading of code on an as-needed basis. In Drupal 7 we have the registry which reads in a list of files from your .info file and then parses them to figure out what classes, if any, are defined in those files. Then, when someone instantiates a new object from a given class the file containing that code will be automatically loaded on an as-needed basis. The PSR-0 standard is essentially a different way of doing this same thing but following a practice that a larger portion of the PHP community uses, rather than one that we made up for Drupal.
There's more in the screen cast as well, so have a look at what it takes to write the simplest of Drupal 8 modules.
Note: As of the recording of this video some changes have been made to Drupal 8 that make this code not work. Most notably the ControllerInterface class which I extend in the video has been renamed to ContainerInjectionInterface. More details https://drupal.org/node/2079895.
More Changes: Changes where made in the .routing.yml file recently so that the key 'pattern' is now 'path'. See the change notice here: https://drupal.org/node/2089727
Even more changes: Drupal 8 now uses PSR-4. You can read all about it in this blog post: Preparing for Drupal 8: PSR-4 Autoloading
To read and see other tours of Drupal 8, check out Kyle's original post, Learning by Trial and Error - Installing and Touring Drupal 8 and Addi's post on Drupal 8: New Multilingual Features.