Framework Implementation
- Routes are just maps between patterns and the code that should run in response.
- The simple case is matching a path directly.
- A common additional feature is to let the pattern have parameters (e.g., by
using regular expressions)
- Frameworks also do a lot of “background” work
- parsing the query string
- parsing any data in the message body
- sending/receiving cookies
- enforcing access restrictions
- connecting to a DB.
Frameworks
- Frameworks feel like a lot of “magic words”, but they all have very similar underlying
principles/features.
- Suppose you wrote 10 different apps. The ideal framework contains all the code that
is identical among the apps so that your code is limited precisely to what is unique
for that given app.
- (Of course, reaching that ideal is not possible. But, we try to get close)
- At this point, you know a lot (but certainly not all) of what you need to know to write a decent web app:
- Client sends URL that is the name of a scripting language file (ruby, python, perl, etc)
- Scripting language runs code to generate dynamic data
- That dynamic data is merged into web page.
- However, at this point a lot of your code would feel repetitive: Many pages would use similar code for things like
- handing forms
- setting up cookies
- logging in
- security
- connecting to the DB
- Similarly, if you were to write many apps, you would find the same code appearing in many (if not all) of the apps.
- At a high level, the job of a framework is to minimize the amount of code you need to write to prepare a web site.
- In other words, the framework provides the repetitive code, and you just provide the stuff that makes your site unique.
- Key challenge: Tradeoff between how much the framework does and freedom to design things your own way
- The more the framework does for you, the more you have to do things according to the framework’s rules.
- The pickier you are about how things are done, the more you have to spell out what you want.
- If you decide that every model of car your company makes will have the same inline-6 engine,
you can produce new designs more quickly; but, your product won’t be as versatile.
- Convention vs. configuration
- Imagine that you’ve written two dozen reservation web sites (airplane, train, ferry, etc.)
- You decide to extract the common parts and use that as a starting point for future reservation sites.
- The more you assume about the structure of the site (convention) the less work that needs to be done for the next site. However,
- The conventions may limit who can use your tool (e.g., what if your framework assumes that users pick seats before checking out?)
- Learning the conventions (i.e., assumptions) can contribute to a steep learning curve.
- Conventions can feel like “magic” to new users (and sometimes, even to old users.)
- One point in looking under the hood is so less of this stuff feels like magic going forward.
- Too much “magic” can feel overwhelming. (At least to me it does.)
- To me, magic is like wrote memorization, which is difficult for me.
- Understanding a bit about how the magic is implemented helps me learn/memorize it (analogous to learning physics formulas)
- You may also want to provide a lot of flexibility (configuration) so the framework can be used by as many different people as possible; however,
- Each thing that must be explicitly configured represents more work for the user.
- Default configurations with options can help; but, then you have to communicate the defaults and the fact that there are options.
- A lot of configuration can make an otherwise elegant design seem clunky.
- For example, it’s nice to have a lot of configurability in a steering wheel (tilt, telescope, etc.); but at some point all the buttons and levers get in the way.
- Consider this convention: When URL points at a directory,
index.html
returned by default.
- Users must learn what the convention is.
- They must also somewhere learn that there even is a convention.
- Now, think about making it configurable.
- If this was configurable, how/where would you specify the alternate filename?
- Is that technique “out of the way”, or does it “clutter” an otherwise elegant solution?
- Also, there is a tradeoff between the steepness of the learning curve and the amount of convention.
- More convention often pays off in the long run, but takes longer to get started.
- There are many different frameworks because there is no single “correct” balance between convention and configurability.
- Also, different frameworks may choose different conventions, thus better supporting different domains.
- Analogous to why there are many different programming languages: With few exceptions, any program can be written in any language; but, some programs are easier to write in C than Ruby and vice-versa.
- Some apps easier to write in Rails
- Other apps easier to write in React
- I imagine it like this:
- “I keep repeating myself. Let me abstract/automate that.”
- Next guy: This is cool; but, I think it should be done slightly different. I’ll make my own.”
Key framework patterns
- Although there are many different frameworks, there are many similar underlying themes with different implementations.
- Pay attention to the underlying themes. Makes it easier to pick up a new framework when necessary.
- (Same principle that makes it easier to learn new languages once you realize 90% of them look like C)
- Think (and ask) about how some of this stuff might be implemented. I find it easier to learn when it doesn’t feel like magic.
- Server-Side vs. Client Side
- Server-Side framework (Rails, Symphony, etc.) does almost all the work on the server – including the generation of the web pages.
- Client-Side framework / Single Page Apps (Angular, Vue, React) sends most of the web page display logic to the client. Server is API-only to collect the data to display.
* Quick overview of node/npm (as there are questions).
- Show how to spin up a quick Express server.
Model-View-Controller
- This is a general software development design pattern. It’s not just for web apps
- Model
- Represents the data / objects
- Access the database
- Provides the business logic
- View
- Controller:
- Ties model and view together
- Basic workflow
- Receives input / action (e.g., HTTP request)
- Calls appropriate model (runs the correct business logic)
- Uses the results of the model’s actions to update view accordingly.
Resource
- Using this model, a URL is, in general, a resource rather than a specific artifact like a file
- Motivation: Many web sites designed around basic operations on objects/resources such as
- User
- Order
- Comment
- Article
- Activity
- Four basic operations:
- Create
- Read
- Update
- Delete
- In principle: We need a path for each operation
mysite.com/user/create
mysite.com/user/4434
mysite.com/user/4434/edit
- ….
- In a non-opinionated framework like Express, you would have to spell all this out.
- Doing so would begin to feel quite repetitive
- Opinionated frameworks like Rails allow you to set everything in one step
- Provided you agree with the conventions (i.e. names) they choose.
Routing:
- URL/Resource identifies a controller (not a specific file) plus the HTML verb (GET, POST, PUT, etc.)
- Most frameworks have a convention and/or configuration that maps resource names to the controller object responsible for that resource.
ORM
- Object-Relational Mapping
- Automatically move between objects and rows in a relational database:
- Table <==> Class
- Rows <==> instances of the class (i.e, objects)
- Columns <===> properties of an object
- In addition, class methods help with things like searching.
- Idea is to avoid having to write SQL (in most cases).
- If classes share names with tables and properties share names with columns,
this convention can avoid a lot of configuration.
- (It also helps that Ruby is dynamically typed)