The potential sources of input to a web-based service are
The URI's path
The URI's query string, with any fragment
The HTTP headers
For certain HTTP transactions (usually those involving the POST protocol method), standard input
A web server typically will treat the request's path as a directory path in a virtual filestore called a web and select either a piece of static content or a CGI script to be run on arguments specified in the query portion of the URI. Although this interpretation is conventional in traditional web servers, it is possible to split up the path into components and use them as database keys, for example. Servers such as Apache offer the capability to perform complex remapping on the path to transform incoming URIs into others, precisely to adapt the classical model into something more flexible. The output from the web server is a function of the inputs, and from one point of view, changes in the site's database are merely side effects of producing the output! By writing your own server, you make it much easier to perform the mappings directly and minimize the overhead involved in setting up the service.
Think of a database mini-web server. This server (refer to Chapter 15 in Python Web Programming by New Riders Publishing) has about the simplest possible interface to its web clients: it gets the operation (HTTP protocol method) and the path (which, technically, includes any query and fragment as well). The server engine to drive that simple content generation scheme created a new object, a dbpage, whenever it received a request and generated its output using the following call:
self.obuffer = dbsource.page(op, path)
Because the creation of a dbpage does not read standard input, the CGI data stream is available to any pages prepared to accept POST method calls, which in practice none of them did. The cgi library module is useful in this context even when a classical web server does not trigger the scripts.