### 1.15.1.2 What Are Middleware Components?

Consider the slightly more complicated example below using the imaginary session handling module `superSession`:

    #!/usr/bin/env python

    import superSession
    session = superSession.session()
    print "Content-type: text/plain\n\n"
    if session.has_key('visited'):
        print "You have already visited!"
    else:
        session['visited'] = 1
        print "This is your first visit."

We create a session object and display a different string depending on whether or not the user has visited the site before. We could follow the approach above and create the following WSGI application to do the same thing:

    def application(environ, start_response):
        import superSession
        session = superSession.session()
        if session.has_key('visited'):
            text = "You have already visited!"
        else:
            session['visited'] = 1
            text = "This is your first visit."
        start_response('200 OK', [('Content-type','text/plain')])
        return [text]

This would be perfectly good and work perfectly well. We could now refactor the code again:

    def exampleApplication(environ, start_response):
        if environ['superSession'].has_key('visited'):
            text = "You have already visited!"
        else:
            environ['superSession']['visited'] = 1
            text = "This is your first visit."
        start_response('200 OK', [('Content-type','text/plain')])
        return [text]

    def session(application):
        def app(environ, start_response):
            if "superSession" not in environ:
                import superSession
                environ["superSession"] = superSession.session() # Options would obviously need specifying
            return application(environ, start_response)
        return app

    application = session(exampleApplication)

We have separated out the session code into a different function and added a key to the `environ` dictionary called `"session"` which contains the session object. Our `exampleApplication` then accesses the session object through the `environ` dictionary. Note how we have renamed our `application` function to `exampleApplication` and mapped the name `application` to the `session(exampleApplication)` object. The WSGI server will still be able to find a callable named `application` and so will still be able to run our application.

The `session` function is now what we call a middleware component as it sits in between the server and the application. It gives the application new functionality but the result of calling `session(exampleApplication)` is also just a WSGI application (because the combined object still conforms to the rules listed earlier) and so the server can still run the code.

The huge advantage of refactoring code in this way is that the session functionality can now easily be added to any WSGI application using our `session` function. By chaining together these middleware components (which do not even have to be based on the Web Modules) WSGI applications can gain an enormous amount of functionality for very little programming effort by using existing middleware components. This helps make code easy to maintain and offers a very flexible programming methodology.