2 Web Frameworks

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Introduction

For a long time my favorite framework was Symfony, until the day I started liking Laminas Mezziomore. There have been many frameworks, and they have been the favorites of many developers, but occasionally one of them gets abandoned by its maintainers. And so the quest for the next “best” framework begins. Something similar that many of us have experienced: the maintainers were tired of version X, so they rewrote the whole thing, and it was released as version Y. Why indeed! The result was a lot of work.

My experience in web development has proven to me that we need to be ready to get rid of a framework. We should also be ready to upgrade our current framework to the next major version, which can be as drastic as switching to a completely different framework. In particular if we’ve coupled our code to the framework, in all the possible documented (and undocumented) ways.

It may be a cliché by now, but we need to keep the framework at a safe distance. If we do so, I’m sure we can save ourselves a lot of expensive development work, trying to get a project up-to-date again. In practice, this “safe distance” means we should not use any framework facilities in some parts of our code, while we allow other parts to make optimal use of the framework’s special abilities. This will give us the benefits of working with a framework (mostly that there’s no need to reinvent certain wheels), while giving us the flexibility to upgrade the framework without too much trouble, or even to migrate to a different framework.

The million-dollar question is: what are those parts, and where should the cut be? To find the answer, let’s first consider what web frameworks have offered us in the past, but also: what will they keep doing for us in the future? What’s the common denominator?

What I think a web framework will always have to do, is:

  • Match the URI of the HTTP request to one of our controllers based on some pattern (routing).
  • Instantiate and invoke the matched controller, providing the request itself as input.
  • Turn the response returned from the controller into a proper HTTP response that a browser can show to the user.
  • Catch exceptions that occur inside the controller and turn them into error responses.

Controllers play an important role here: they are the place where, as developers, we can finally do something. But what we do is often quite repetitive: we load data from the database, apply the changes to it that were submitted using a form, we save the resulting data, and finally we render a nice page for the user. Framework authors try to make our controllers simpler by removing some of this duplication, and providing convenient shortcuts. This is often achieved with magical features that are implemented by running some code before and after our controller code. For instance, the framework may magically do the following things for us:

  • Validate request data
  • Load an entity based on a matched URI parameter and pass it as a controller argument
  • Provide the logged-in user object as a controller argument
  • Render a template based on an annotation

These features count as magical because for the reader it’s not clear what happens, when, and based on what input.

Controllers

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Show How the Response is Created

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Only Use Constructor Injection for Dependencies

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Make Every Step Explicit

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Controllers Have No Parent Class

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Every Action Has its Own Controller Class

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Should We Use an HTTP Abstraction Library?

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Rules for Decoupled Controllers

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Forbidden Parent Classes

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Allowing Only Parameters of a Certain Type

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Enforcing Return Types

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

One Action Per Controller

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Views

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Pass All the Data That the Template Needs

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Don’t Pass Objects That Don’t Belong in a Template

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Rules for Decoupled Views

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Don’t Use Certain Global Variables in a Template

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Don’t Use Certain Functions in a Template

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Don’t Pass Entities to a Template

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.

Conclusion

This content is not available in the sample book. The book can be purchased on Leanpub at http://leanpub.com/recipes-for-decoupling.