Web Development: The Static Fundamentals
Tags: webdev, beginners, javascript, tutorial
Published: 2021-07-10 11:47:00

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.

## Frontend Web
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](https://dev.to/sapinder_dev/the-dynamic-web-40kk) of this series. 😉

> HTML stands for HyperText Markup Language, where  [HyperText ](https://en.wikipedia.org/wiki/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?

{% codepen https://codepen.io/sapinder_dev/pen/wvdWZBG %}

Most likely not! But what about this one?

{% codepen https://codepen.io/sapinder_dev/pen/dyWXLoL %}

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
<!-- HTML -->
<button>I'm a Fancy Button!</button>
```
```css
/* 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.
```css
button {
  color: white;
}
/* This will override the previous value for 'color' */
button {
  color: black;
}
```

### JavaScript
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.

{% codepen https://codepen.io/sapinder_dev/pen/wvdWZMW %}

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.
```javascript
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**](https://developer.mozilla.org/en-US/docs/Glossary/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](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model#html_dom) 
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-
```javascript
// 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.
```javascript
/* 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. 😛
 
## Backend Web

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!** 😅

### Meet Node.js
We have [Node.js](https://nodejs.dev/learn) that is a [JavaScript runtime environment](https://olinations.medium.com/the-javascript-runtime-environment-d58fa2e60dd0). 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](https://developer.mozilla.org/en-US/docs/Web/API/Storage) for storing website's data on client's system, [CSSOM](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model) 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.

### Working of a Server
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](https://developer.mozilla.org/en-US/docs/Web/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
<!-- 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](https://en.wikipedia.org/wiki/Pseudocode) for this job-
```js
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.

### Databases
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](https://www.logianalytics.com/relational-vs-non-relational-databases/) 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.

### Server-side APIs
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](https://sapinder-pal.github.io/IP-Address-Tracker-Vanilla-JS-CSS/) 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](https://geo.ipify.org/) 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](https://api.thecatapi.com/v1/images/search) of [TheCatApi](https://docs.thecatapi.com/), 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](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/).

To summarize so far-
1. We have HTML, CSS & JavaScript working together on client-side
2. We have a Server handling client's requests/responses, using Node.js
3. We can also use Databases to store data
4. We can also serve an API instead of an application

Now let's head to the next section.

## Hosting Providers And Domains
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](https://computersciencewiki.org/index.php/Ports) 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**](https://en.wikipedia.org/wiki/Domain_name) 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](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.


> <strong>Fun Fact</strong>
<p>You can have any number of subdomains once you own the domain name. Also, www is a subdomain too!</p>


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.

## Version Controlling
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](https://careerfoundry.com/en/blog/web-development/whats-version-control-and-why-do-i-need-it/) 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](https://git-scm.com/). 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` and `development`. `main` is the default branch when git is implemented, whereas I keep a separate `development` branch for development purposes. The number and purpose of branches may increase in large scale projects.
- **Stage** - There is a [staging area](https://git-scm.com/about/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 can `merge` them into my `main` 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.

### Remote Repositories
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](https://en.wikipedia.org/wiki/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](https://github.com) and [Gitlab](https://about.gitlab.com/), 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](https://github.com/sapinder-pal) (*No, I don't mean it!* 😅).

## Wrapping Up
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](https://dev.to/sapinder_dev/the-dynamic-web-40kk) that powers modern websites we see around. So stick around if you think my content is worthy enough for you! 
You can <b>_follow me_</b> if you want to never miss any of my future content!