I have always had a personal gripe with the term "full stack". I never identified myself as a full stack engineer, having spent my whole career focusing either on design or front-end development. My opinion was that a true "full stack" engineer was a bit of a myth (how can you be an expert at so many things?!). Having spent my whole career working with engineers that were considered full stack to a degree - my experience was that these "full stack" engineers had a vertical specialism and a broader horizontal understanding that allowed them to work well and collaborate within a team. I was content sticking to my front-end and design vertical, without ever feeling the need to get involved in the back-end, architectural or ops work.
I still have this opinion, but over the last year my perspective has shifted. I now think every software engineer, no matter how specialized or skilled they are can work competently as a "full stack" engineer. In this post, I'll dive in to how I came to this conclusion.
In the early days of computer programming, computer "programmers" would punch holes in to physical cards (the holes would correspond to instructions) that would be fed in to a machine the size of a room. Many days later, the results would come back to the programmer. These were simple mathematical programs performing calculations for things like aviation and mechanical engineering, and the programmers operating these instructions were typically highly skilled mathematicians.
As computing became more successful, more efficient means of communicating with computers were invented and developed with the introduction of higher level programming languages: Assembly (1951), FORTRAN (1957), C (1972), C++ (1980), Python (1991), JavaScript (1995), Go (2009), Swift (2014) and we're not finished inventing new ways of building software yet! Looking at this small subset of programming language developments, it's clear to see a trend. The more that languages are developed, the more popular computing becomes and the more accessible computing becomes for the masses.
We've looked at how programming language design has evolved over time, and the same evolution has happened for frameworks that help software engineers build software and systems. Speaking from a front-end perspective, I'm fortunate enough to have seen front-end development grow from simple HTML based applications sprinkled with vanilla JavaScript (or jQuery) through to very modern front-end application stacks (and everything in-between).
In some respects it's difficult to see how a newcomer to software engineering would find a modern software stack "simple", but this isn't really the point - the newcomer would be able to build more complex software more quickly and with higher quality than the same software engineer entering the field 10 years ago. It's down of the development and refinement of programming languages and frameworks that allows for the accessibility and productivity of modern software engineers.
I truly believe that anyone can be a productive and professional software engineer using modern tooling should they have the necessary desire and willingness to learn. I don't think the same could be said for software engineering 20 years ago.
So what does all this have to do with modern full stack development? Hopefully I've made the case that software engineering is becoming more and more accessible over time, and naturally this progression means that existing software engineers are able to broaden their skillset in to other areas of software engineering much more easily than before. It's never been easier than it is today to learn the skills necessary to be considered a full stack engineer.
I've thought about this over the past few years as I have deepened my software engineering vertical in to front-end engineering and have made it a personal mission over the past year to expand my horizontal skillset with practical backend and infrastructure experience.
I set myself a goal in the summer of 2018 that I would have designed, architected and built a full-stack web-application using modern tools, languages and frameworks and have it running in production with all the bells and whistles that a modern web application is expected to have.
I already have expertise in front-end design and development with modern languages and frameworks, but I've never really built any substantial back-end APIs, databases, storage solutions, deployment etc etc in the past, and I knew that this would be where I needed to spent most of my time.
A year really isn't very long to become proficient in all the areas I needed to be, so I needed to be sensible with my choice of languages, tools and frameworks.
Originally, I architected the application as separate front-end and back-end monoliths, deployed to traditional long-running servers.
Honestly, I didn't find building the back-end too difficult as I tried sticking to familiar languages and programming patterns where I could and followed tutorials and examples for the parts that I hadn't any experience in. However, what I did find particularly difficult was dealing with the "ops" of the project, that is deployment, provisioning and updates. I would often break the app completely during updates, particularly when updating the database models and running migrations. What I realized was that I had to switch my mind in to thinking about ops separately from thinking about the application code I was writing. I started to invesigate different technologies that might make this easier.
I found serverless to be a good solution because it allowed me to write my code and deploy it through the framework as code. What's more, I could write my back-end business logic as I did my front-end, as functions, and have it running and deployed without having to think about servers or ops at all. I didn't have to worry about the database going down, or the back-end APIs falling over with traffic spikes etc. I could plug in to a rich ecosystem of plugins and products that provided functionality such as automatic database updates, continuous integration and delivery at a push of a button and logging, metrics and exception tracking without having to build any of it myself.
In some respects I feel as though I have cheated at my original goal, but really looking back at history, this trend seems like a natural evolution in abstraction. I only really had to learn the framework, and the rest of my time was spent writing the code that pertained to the application I built.
I've worked on this application for a year, and so far I have been introduced to AWS Lambda, AWS S3, AWS CloudFormation, AWS DynamoDB, AWS API Gateway, AWS IAM and many more services all abstracted away from me via the serverless framework. Although I would struggle to set up all the infrastructure and maintain it without the framework, I have working knowledge of all of these back-end / ops technologies and my goal to become a more full-stack engineer has well and truly been achieved.
In retrospect, becoming more full-stack has let me become a better front-end developer and designer. I spend much more time in the planning stages of a feature, thinking about everything from the user-experience all the way down to the infrastructure deployment to support it. As a result, the features I design and build with my colleagues are much more robust and well thought out, leading to quicker delivery with higher quality. I'd urge any software engineer who thinks that "full stack" is out of reach to give it a go and build something truly end to end.