31
Web Development: The Static Fundamentals
This is the first part in the series where I will provide a foundational understanding of the websites that you see around, and use daily. In the first part, we'll get to know the fundamentals of static web development. I won't focus much on implementation, because this is to get an idea about the kind of things that exist in this field. So, I think we're ready to begin now! 👨🏫
In the most basic sense, a website is no different from a native app, e.g. android/ios app; except that it can only do things that a web browser allows it to. It can't run on the client's system like other apps do, because it is rendered inside a web browser; and it is the thing that only a web browser understands.
There are two major parts of web development- frontend (client-side) and backend (server-side). Let's discuss the front end first.
A website is a collection of web pages, which are just plain HTML files. When you make a request to a website's server, your browser receives a ton of data in response; but one thing that is never going to be missing is HTML.
Each web page is an individual HTML file. Every time we navigate to a different route, the browser makes a new request to get the HTML file for that page. For example, if you navigate from /home to /about-me route, it would make another request to the server to get HTML file for /about-me page.
The best way to check is to notice the loading indicator in your browser. If it indicates that it's loading, you have essentially made a request to the server; and it's waiting for the response. In case you wonder why it doesn't happen on this site, you'll get to know the reason in the next part of this series. 😉
HTML stands for HyperText Markup Language, where HyperText refers to text that contains references to some other text. So essentially, that's how you jump from one web page to another.
Now, do you like the way this button looks?
Most likely not! But what about this one?
The first one is a plain HTML button with default styles, but the second one utilizes CSS to apply custom styles. Below is a sample code for this fancy button-
<!-- HTML -->
<button>I'm a Fancy Button!</button>
/* CSS */
button {
color: value; /* consider 'value' as a placeholder */
background: value;
border: value;
padding: value;
border-radius: value;
box-shadow: value;
}
CSS stands for Cascading Style Sheets, which actually states what it does. The styles are applied from top to bottom in the order they are defined, just like a cascading waterfall. Any repeated style would override its previous corresponding values, as in the following example.
button {
color: white;
}
/* This will override the previous value for 'color' */
button {
color: black;
}
Now, just HTML & CSS ain't enough for a modern website. For example, that Fancy Button above does nothing when you click on it. But a button is really meant to trigger some action. Now click on the button below to see what happens.
You guessed it- it's JavaScript! 😄 It adds functionality to these showpieces. Just like HTML & CSS, JavaScript is a client-side language; meaning that it is interpreted and executed by a web browser. It can't run natively outside a web browser, unlike C++, Java, Python, and other commonly used server-side languages.
Working in JavaScript is similar to many other languages, for example, the following statement declares a variable named myName
that we can do anything with.
var myName = 'Sapinder Singh';
We can use and manipulate this variable as and when needed. But in JavaScript, we don't want to work with these variables only; we instead want to operate on HTML elements present on the page! So how do we operate on HTML elements in JavaScript?
You must have at least heard of the term API (Application Programming Interface). As the name suggests, an API serves as an interface for different pieces of software to communicate with and provide data to each other.
When it comes to interacting with HTML, JavaScript needs DOM API
that stands for Document Object Model. It provides the HTML document to JavaScript in the form of an Object Model. The root of this inverted tree-like object is the document itself. Each element in the document gets its own node that goes as deep as the number of children elements it holds.
So if I want to select that "Fancy Button" in JavaScript using DOM API, I would do this-
// assuming the button does have an id
var fancyButton = document.getElementById("fancy-button");
Instead of assigning a regular value to some variable, I would have to assign it a DOM element. I can then treat this variable like an actual element on the page. The following statement implements a part of that 'click' thing on the button.
/* Don't worry if you don't understand the syntax,
you're here just to understand what it does. */
fancyButton.onclick = () => alert("I've been clicked! :)");
So in essence, HTML, CSS and JavaScript form the basis of front end of a modern website. We can-
- have one or more HTML files (and other optional files such as .css, .js, etc., linked from within HTML)
- open the root HTML file in any web browser
- and see it render in the form of a web page
But as you may guess, it's totally useless as long as only we can see the web pages. That's why we now need to head to the next section. 😛
A web server is needed in order to serve our web pages to the world. For this task, we have a lot of server-side languages such as Java, PHP, Ruby, Python, C++, etc. I mentioned earlier that JavaScript is a client-side language, because it can not be run outside a web browser to act like a web server. Now I'm ready to admit- that was kind of a lie! 😅
We have Node.js that is a JavaScript runtime environment. A runtime environment combines different tools and technologies to provide a suitable environment that enables it to run a certain program or application.
Your web browser too provides a runtime environment for JavaScript that supplies various APIs to the core JavaScript engine like DOM for parsing HTML, Storage API for storing website's data on client's system, CSSOM for manipulating styles using JavaScript, etc. But the core part of a JavaScript runtime environment is the JavaScript engine.
Google Chrome and other Chromium-based web browsers use Google's V8 engine for running JavaScript, which is written in C++. Interestingly enough, Node.js also uses the same engine. But instead of providing APIs like DOM or so, it uses other tools that allow access to Operating System, File System, Networking, etc. This, as a result, enables us to use JavaScript as a server-side language.
Node.js is a popular choice among other backend languages nowadays. A major advantage for those coming from frontend part
is that you don't have to learn another language to setup a server! You're all set if you know JavaScript well enough.
A server is always up and running (if not crashed! 🙄), listening to requests and sending appropriate responses to its clients. The type of response depends on what type of request a user makes. These are called methods. Following are the two most commonly known request methods used over HTTP:
-
GET - This method should be used for retrieving a resource from the server. As an example, when you visit any
website, the browser makes a
GET
request to the server asking for a web page present on that route. -
POST - This method should be used for posting/submitting data to the server, usually when creating a new resource. When you fill up a web form, that form mostly uses
POST
method as shown in the snippet below.
<!-- HTML -->
<form method="POST">
<!-- The form fields go here -->
</form>
I can't show you the actual implementation of how a server handles requests and responses in Node.js because it might be a little complex for beginners; but here's a Pseudo code for this job-
CREATE an http server using http.createServer()
CALL server.listen() to activate the server
// Now handle requests from different routes, e.g. '/home' or any route
IF request.url EQUALS '/home'
SEND '/home.html'
ELSE IF request.url EQUALS '/create-user'
// the user wants to visit the page where it can create a new account
IF request.method EQUALS 'GET'
SEND '/create-user.html'
// if the method is POST, it means the user submitted a form on '/create-user' route
ELSE IF request.method EQUALS 'POST'
SEND newlyCreatedAccount
This was to give you a brief idea of a server. If you notice the handler for POST
method on /create-user route, we're trying to create a new user based on the data received via request
object; and then provide that newlyCreateAccount
to the user. But we actually need to store that account to remember it in the future. So, it's time to head to the next section.
You may already have an idea of what a database is. A Database is like a store with a certain way of organizing and working with data. A common term you would hear relating to databases is CRUD; an abbreviation for Create, Read, Update and Delete. These four are the most basic operations that a database performs.
There are many types of databases, but the two major categories are Relational and Non-Relational. Sometimes they are also referred to as SQL (Structured Query Language) and
NoSQL respectively. Let's take a look at each of them-
- Relational/SQL Databases - These types of databases store data in a table-like format, where each row represents an entity while each column holds certain data about that entity such as Name, Address, etc. MySQL and PostgreSQL are two popular relational databases to consider when working with Node.js.
- Non-Relational/NoSQL Databases - The 'No' in NoSQL means Not only, meaning that it can be of any form. These are more flexible than their SQL counterparts. The most popular NoSQL choices with Node.js are MongoDB and Redis.
Choosing a database depends on the type of data you're going to store, and it is advised to research about different options before making a choice to get optimal performance.
Ever wondered how the weather app on your cell phone collects so much amount of weather info? And how does google maps know what place is where? And where does this little ip-address-tracker-app get all the data from?
It's all done via APIs. A server-side API is similar to a web server, but instead of serving a web app, it serves data to other apps so they could make use of it. That ip-address-tracker-app utilizes IP Geolocation API by IPify to collect data about different IP addresses.
An endpoint can be thought of a final destination that we can visit to get data or perform some other action related to that data. Endpoint may be considered a fancy name for URL. Visiting any of the endpoint of an API should return some data rather than a web page. For example, if you visit this endpoint of TheCatApi, you shall receive an object consisting of a URL of some random image, along with other details about the it.
We can have any number of endpoints in a server-side API, but the API has to follow some well-thought architecture to be accessible and maintained in a large scale project. The standard protocol for web APIs is to use a RESTful architecture. If you wish to learn more, refer to this post about RESTful API.
To summarize so far-
- We have HTML, CSS & JavaScript working together on client-side
- We have a Server handling client's requests/responses, using Node.js
- We can also use Databases to store data
- We can also serve an API instead of an application
Now let's head to the next section.
The so-called web server that we know about so far yet is on our local machine only. We can run the server in background, and open, for example localhost:8000, in the browser to see our website. 8000
is a port number. But instead of hosting our server locally, we now need to host it somewhere else to make it available to the world. We want to deploy our app to a hosting
provider that would run our server 24*7 on its huge machines.
There you would also need a domain name for people to be able to access your server on the internet, because now it can't be reached via localhost. A domain name is the *.com part of a url. For
example, in my website's url https://blog.sapinder.dev, the domain name is sapinder.dev where dev is a top-level domain just like com, org, etc. If you wonder, the blog part is a sub-domain.
Fun Fact
You can have any number of subdomains once you own the domain name. Also, www is a subdomain too!
Apart from buying a domain name, we also have to pay regular charges to our hosting providers because they run our server 24*7. But most of the hosting providers offer free tier services with limited resources, and we can upgrade our accounts as our requirements grow. Meanwhile, free tier services are mostly more than enough for beginners, and they also provide a free domain! The main caveat is that it ends with their default domain names. For example, *.herokuapp.com for Heroku, *.netlify.app for Netlify, and so on. If you want your own domain name, to look actually professional, you will have to buy one.
Maintaining the code is also really important, as it's the only way to identify & fix currently present bugs, as well as to bring new features to an app. Version Control Systems allow us to track & add changes, and even revert the whole app back to a previous version! Now you know how powerful these systems can be.
The most widely used VSC is Git. There are a few terms that you should know when using Git, a few of which are-
-
Branch - Branching allows developers to keep their code repositories into separate branches, each for a specific purpose. For example, I usually maintain two different branches for my code, namely
main
anddevelopment
.main
is the default branch when git is implemented, whereas I keep a separatedevelopment
branch for development purposes. The number and purpose of branches may increase in large scale projects. -
Stage - There is a staging area in git that holds all the ready-to-be-made changes in our code. We add the changed files in our code to staging area via
git add <file-name>
command in order to be able to review the changes before making a final commit, which leads us to the next point. -
Commit - After we have reviewed the changes, we're ready to run
git commit
command that finally creates a new version in the git history for our code repository. -
Merge - We can merge the changes made to any branch into another branch. Say I made changes to
development
branch, and I've tested them as well, now I canmerge
them into mymain
branch to publish changes to the server.
We can also revert
our current version to any of the earlier commits by using that commit's ID. There are many other things that version control systems allow us to do that you would get to know as you use them.
What is the probability that your app code, saved in some location on your local system, is going to be safe forever? What if it gets deleted, or accessed by someone else? You get it- we need to store it online so that only we could access it anytime and on any system.
If somehow we loose the local repository, we can clone it from our remote respository along with all of the git history!
Remote repositories are not always private, but public too. They are known as Open Source projects that anyone can contribute to because their source code (or just code) is openly available to other developers in the community. For example, Firefox, Node.js, VLC Player, Linux, etc., are all open-source projects that anyone can contribute to.
Speaking of cloud-based/remote repository platforms, two of the most popular ones are Github and Gitlab, the former being the leading solution. These are like Facebook for developers and programmers to showcase their projects, as well as to maintain them. If you want to take a look, here's my Github profile (No, I don't mean it! 😅).
So, this was my attempt to give you the best overview of fundamentals of web technologies. In the next part of this series, we will learn about the dynamic part of web that powers modern websites we see around. So stick around if you think my content is worthy enough for you!
Don’t forget to check out my blog where I have a Newsletter that you can subscribe to!
31