Sling's Request Processing Revisited
Back in November last year I wrote a post about Sling's request processing. Things have changed quite a bit till then so here's a revised version.
In Apache Sling each (http) request is mapped onto a JCR resource, i.e. a repository node. This is very different from other web frameworks you might be familiar with, say, Struts or Rails. In these frameworks a request is mapped onto a controller, i.e. a url really addresses application code, so the application developer usually implements some application logic that retrieves model data and passes it on to the view.
Just like Rails or Struts, Sling implements a model-view-controller architecture. However, in Sling a request addresses a piece of content. The mapping between request and model (data, content) is accomplished through the url so there is no need for further custom mapping logic.
Node selection
So, how does this work in detail? Consider an http GET request for the url:
/content/corporate/jobs/developer.html
First, Sling will look in the repository for a file located at exactly this location. If such a file is found, it will be streamed into the response as is. This behavior allows you to use Sling as a web server and store your web application's binary data in the repository as well.
However, if there is no file to be found Sling will look for a repository node located at:
/content/corporate/jobs/developer
(i.e. it drops the file extension). If this node cannot be found Sling will return the http code 404.
Script folders
The scripts that Sling uses to process http requests are stored in subfolders of "/apps". Those subfolders are usually of type nt:folder, but that's not a requirement.
Script selection
Nodes can have a special property named "sling:resourceType" that determines the resource type. Let us consider the simplest case (using the example request URL from above) and assume that the resource type is, say, "hr/job". The selected script will then be "/apps/hr/job/job.esp" (the last part of the resource type will have to be the file name). This works for GET requests and URLs ending in ".html".
Requests using other request methods, say POST, will cause Sling to look for the script at "/apps/hr/job/job.POST.esp". Request URLs ending in something else than ".html", say ".pdf", will make Sling look at "/apps/hr/job/job.pdf.esp". The convention to distinguish the two cases is that http methods are all uppercase and the extension of the request is all lowercase.
In a content-centric application the same content (aka nodes) must often be displayed in different variations, e.g. as a teaser view and as a detail view. In Sling this is achieved through selectors. The selector is specified in the URL like e.g.
/content/corporate/jobs/developer.detail.html
For this URL Sling would locate the script at "/apps/hr/job/job.detail.esp"
If the selected resource has no special resource type a script will be looked up based on the content path. For example, the script for /content/corporate/jobs.html will be searched in /apps/corporate.
Script engine
The ".esp" extension of the scripts used in the examples above indicates script engine to use. ".esp" stands for Ecma script and internally uses Rhino, Mozilla's Javascript engine. Other supported extensions are ".rb" for JRuby scripts, ".jsp" for JSPs or ".jst" for client-side execution (".jst" denotes Javascript template).
Some interesting special cases
The examples above describe rendering nodes as html or as a pdf. Howevere, there are also some built-in renderers for json and txt. The corresponding node presentations are located at (using the example form above):
/content/corporate/jobs/developer.json
and
/content/corporate/jobs/developer.txt
respectively.
For http error handling (404 or 500) Sling will look for a script at "/apps/sling/servlet/errorhandler/404.esp" and 500.esp, respectively.
More on script selection
If you need to find out more on the details of script selection in Sling have a look at Sling ticket 387 where developer Felix Meschberger a lot more on the script resolution process.

[1] http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java?view=markup
This is awesome!