The advantage of breaking up the request process into phases is that Apache gives a programmer the opportunity to "hook" into the process at any of those phases. Apache has been designed with modularity in mind. A small set of core functions handle the basic tasks of dealing with the HTTP protocol and managing child processes. Everything else is handled by modules. The core supplies an easy way to plug modules into Apache at build time or runtime and enable them at runtime.

Modules for the most common tasks, such as serving directory indexes or logging requests, are supplied and compiled in by default. mod_cgi is one such module. Other modules are bundled with the Apache distribution but are not compiled in by default: this is the case with more specialized modules such as mod_rewrite or mod_proxy. There are also a vast number of third-party modules, such as mod_perl, that can handle a wide variety of tasks. Many of these can be found in the Apache Module Registry (http://modules.apache.org/).

Modules take control of request processing at each of the phases through a set of well-defined hooks provided by Apache. The subroutine or function in charge of a particular request phase is called a handler. These include authentication handlers such as mod_auth_dbi, as well as content handlers such as mod_cgi. Some modules, such as mod_rewrite, install handlers for more than one request phase.

Apache also provides modules with a comprehensive set of functions they can call to achieve common tasks, including file I/O, sending HTTP headers, or parsing URIs. These functions are collectively known as the Apache Application Programming Interface (API).

Apache is written in C and currently requires that modules be written in the same language. However, as we will see, mod_perl provides the full Apache API in Perl, so modules can be written in Perl as well, although mod_perl must be installed for them to run.