RESTful Microservices, Client-Side Frameworks, Containerization (2010s)
Learning objectives
- You know of some of the milestones in web development from the 2010s.
The increase in the use of AJAX for building dynamic web sites also led to thinking how the data should be served from the server. A key building block was the introduction of the Representational State Transfer (REST) architectural style (proposed in a thesis in 2000), which outlined architectural constraints that guide client-server communication. These include a clear identification of resources, the ability to manipulate the resources, self-descriptive communication, and using hypermedia as the engine of application state. This style was adopted for building interfaces for web applications, which led to the emergence of RESTful web services.
We discuss RESTful web services in more detail in the chapter on Application Programming Interfaces.
With the increased attention to AJAX applications that allowed dynamic update of page contents without reloading the entire page, client-side libraries and frameworks started to emerge to make the task easier. These libraries included Backbone.js (2010), Knockout.js (2010), AngularJS (2010), Ember.js (2011), and so on. The development was so rapid that it was difficult to keep up, which also spawned a handful of memes about JavaScript developers and client-side web development.
To see some of these memes, often depicting developers moving their attention to new frameworks and libraries, run a Google images search with "new javascript framework meme".
These frameworks provided structure for building client-side web applications and made it easier to bind the client-side functionality with the server-side functionality. This movement -- jointly with AJAX -- also led to the emergence of the concept single-page web application (SPA), where the JavaScript functionality is loaded into the browser when the user first visits the site, and subsequent interactions with the server are done using AJAX calls.
During this time (and also already late 2000s), the role of relational databases for web development was questioned as there were concerns about their scalability. NoSQL databases -- non-relational databases that did not use SQL as the query language -- gained a foothold. These databases were often schemaless, and were designed to scale horizontally. Some of the more popular NoSQL databases included MongoDB (2009) and Redis (2009). Since then, relational database provides have built in much of the functionality that was missing, and the NoSQL databases have also evolved to support more complex data models, unifying the two approaches to form the term NewSQL.
The way how developers worked and the developer experience was also paid more attention to, and it became more common to continuous integration and continuous deployment (CI/CD) pipelines, where the code is automatically tested and deployed to production. One further advancement in this area was also the adoption of containerization tools such as Docker, which allowed packaging applications and dependencies into containers that could be run on any machine that had the containerization tool installed (at least until the emergence of the ARM64 architecture, heh..).
We discuss containerization and CI/CD in later chapters of the course.
An additional trend that started to emerge was the use of JavaScript for building server-side functionality. This was made possible by the introduction of the Node.js (2009), which is the predecessor to Deno that we are using in the course. Node.js allowed running JavaScript code on the server-side, and it also came with a package manager, npm, that made it easy to install and use third-party libraries. This led to the emergence of the MEAN stack, which consisted of MongoDB, Express.js, AngularJS, and Node.js. The MEAN stack was one of the first full-stack JavaScript frameworks, where the same language was used on the client-side and server-side -- this also slowly led to the emergence of the term "Full Stack Developer".
Another key milestone in building client-side functionality was the increased emphasis on building applications out of components that together form a whole, instead of more explicitly modifying the elements shown on the page. This idea, although already widely present in e.g. object-oriented programming, led to the emergence of component-based web frameworks such as React (2013), Vue.js (2014), and Svelte (2016).
The term library and framework are used here somewhat interchangeably. Some could argue that React is a library and not a framework, but the distinction is not that important for our purposes.
The way how applications are composed and rendered also gained more attention, in part due to the potential weight of the SPA applications in terms of code. This has sparked efforts on server-side rendering (SSR), where the application (or parts of it) is rendered on the server and the resulting data is sent to the client on-demand. This allows the client to display the page faster, and also improves the search engine optimization (SEO), making the sites easier to find. As an examples, Gatsby (2015) and Next.js (2016) and Nuxt.js (2016) were introduced to address the issue.
As an example, in 2019, the median we page consisted of approximately 1900KB in size and loaded in 74 requests (source: Web Almanac, 2019) -- JavaScript makes up for the majority of these requests.