Public Learning

project-centric learning for becoming a software engineer

Week 1: A Recap

Thursday: Kicking It Off

“A magic dwells in each beginning” is a familiar quote by a German author and it could not be more true. I spent quite some time on Thursday to get set up, but everything still felt wonderfully special. Without the shackles of a full-time job, I’m finally able to put a healthy dose of my daily energy towards deepening my programming knowledge and ultimately building a portfolio project that is not a todo app.

I set up my GitHub repository for this undertaking (here), organized some of the stuff I’ve done so far, read up on a few learning approaches, wrote my first real blog entry and then actually got my hands dirty with Node.js again.

Friday: Taking A Huge Bite

Express In Action, cover I already mentioned my rather simple approach to learning that has successfully carried me through Launch School: doing extensive Markdown notes. While I still wonder if that will be as beneficial now as it has been in the past, I’ve nevertheless continued with it. Working through big parts of the Express in Action book by Evan Hahn (Manning, 2016), I did extensive note taking on the basics of the Express framework for Node.js (you can find those notes here).

The actual Launch School Capstone program has students learn about Ruby on Rails as part of a deeper backend education, and it’s probably a truly enjoyable treat to learn. But alas, Rails isn’t as prevalent in the wild on this side of the Atlantic Ocean, so I felt it would be better to focus on Express.js instead. That also meant choosing the more barebones, unopinionated framework of the two: Rails has a lot of functionality included out of the box, where Express is very similar to Ruby’s minimal Sinatra framework.
In essence, Express wraps around the http module provided by Node.js. Where normally http expects you to write one big function to handle the whole request/response cycle, Express splits some of that functionality up and puts heavy emphasis on middleware:

const express = require('express');
const app = express();

app.use((req, res, next) => {
  // access the request and response objects
  next(); // call the next function in the middleware stack
});

There is a certain elegance to it, because every piece of functionality in an Express app is added into the cycle of middleware functions that get executed in the order they were defined. The only three arguments for such a middleware function are req (an object containing information about the request, like headers or cookies), res (the response object that provides access to a few methods that can set the response’s status code and send various types of content) as well as next, which is just a reference to the next middleware function in the stack. Want logging? Write a piece of code that reads and processes info from the request object and call next() to continue. Want to add session functionality? Write middleware that reads cookie information from the request object or sets new cookie contents on the response object and call next().
This minimal set of features makes Express flexible, but also introduces a dilemma. If you don’t want to reinvent the wheel and implement the aforementioned functionality for logging and session management yourself, you’re going to add a lot of third-party libraries to a project. And the npm ecosystem with its recursive dependency building relies heavily on atomic packages, each implementing some necessary basic functionality that is either missing in the Node.js or Express standard library. It feels strange to develop a small application and have over 50 packages sitting in my node_modules folder, with each added dependency pulling in even more sub-dependencies.

As I was feeling the itch to do some real development on Friday, I decided to start working on a small full-stack application with Express to get my feet wet in the seas of code instead of just doing swimming motions from the safety of an umbrella on the beach. I sketched out a small design for a CRUD app and went to bed early to continue work the next day.

Saturday: Smelling The Ashes

Express in Action presented a small example app that gave me a good idea of how to design an actual application. Express lends itself really well to an MVC design, so I started defining a few routes with their respective controllers, added support for templating and had a quick skeleton app up in an hour or so.
Afterwards, I perhaps got a bit too ambitious, but I was bored by the idea of just doing an oversimplified web app again. Sure, I could have ephemeral data persistence again by storing everything in a simple data object or do very naive account and permission management. But I no longer need to learn about the why, I want to learn about the practical how. So in a whim, I decided to expand the scope of that first app by quite a margin: I wanted to do implement some real authentication and actually use persistent data storage.

Enter Passport.js and MongoDB/Mongoose. The former is one of those third-party libraries that provide functionality that would be cumbersome to implement on one’s own (authenticating users via either a username/password system or by using one of the auth systems from the likes of Google, Facebook or Twitter). MongoDB is a NoSQL database that I had some previous knowledge of. As a refresher and an introduction to the fabulous Mongoose ODM I watched Scott Moss’ Introduction to MongoDB course from Frontendmasters (link). Mongoose’s API is extremely intuitive and I can certainly see the charm of using a database that closely models JavaScript’s object structure and only requires a loose compliance to any kind of schema that regular SQL so heavily imposes from the start. It’s certainly a good fit for the quick prototypal development I had in mind.

The more difficult part was the integration of Passport. In general, protecting an Express route with Passport is really easy, because - again - it’s just about dropping in another middleware function:

app.post('/login', passport.authenticate(
  'local',
  {
    successRedirect: '/',
    failureRedirect: '/login'
  }
));

Passport then populates the request object with a simple isAuthenticated method and the user’s information and that’s it.

My desire for a better understanding of what actually happens behind the scenes came from some difficulty in actually integrating everything into my project’s existing code. Wouldn’t I serialize user information for session storage in my Mongoose model? How do my flash messages for any errors actually receive information from Passport? I resorted to some hack-and-slash coding before taking a step back. It was like I never did Launch School: without the guidance of course material, I got impatient and wrote code without having a clear mental model of how it would work. A dumb mistake, but one that was easily rectified by perusing Passport’s documentation and parts of its source code. Nevertheless, I probably wasted about an hour or two falling back into pre-LS methods of banging my head against a problem without a clear plan.

Web Scalability for Statup Engineers, cover In the evening, I started reading Web Scalability for Startup Engineers by Artur Ejsmont (McGraw-Hill Education, 2015), another book taken directly from the reading list of the actual Capstone program. I’m about halfway through right now, and enjoy it for providing a very good overview of the complexity of disributed systems. After a bit of frustration earlier, I found comfort in the realization that everything I read fits well into my mental model of the moving parts of a modern, distributed web application.

Sunday: Sharing Pain

Sunday brought some much needed external feedback and reassurance. I met with my regular study group from Launch School and both Bharat and Catherine (thanks, guys!) patiently endured my rant about how it feels to leave the safety and comfort of a structured curriculum. I also met with another student who is going to start the Launch School Capstone program in two weeks and we talked a bit about learning approaches and both of our upcoming journeys.

The rest of my working hours was spent dissecting Passport again (and fixing most of the remaining issues I had from the day before), as well as reading two more chapters of Web Scalability …. I also set up my Intel NUC mini-PC again with Ubuntu Server to have a small server that can act as a 247-running platform for various databases, nginx and some first Docker experimentation later this month.

Summary

🎉

Time spent in my first week: (well, my first four days) 21.5 hours 1


  1. My time tracking method consists of scribbling down roughly how much time I spend in front of my machine doing actual reading and/or programming. It does not include time spent reading paper books in the evening hours, talking to other people or lying in bed at night, nonsensically panicking about a perceived lack of progress. So, those numbers should be taken with a grain of salt. All in all, I’m still getting up to speed and I expect to soon hit at least 50 to 60 hours consistently in a full week. [return]