Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
illicitonion committed Jan 2, 2025
1 parent e1e6694 commit 4026023
Show file tree
Hide file tree
Showing 12 changed files with 425 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
+++
title = "Limitations of backends"
headless = true
time = 20
facilitation = false
emoji= "📖"
objectives = [
"TODO",
]
+++

TODO
85 changes: 85 additions & 0 deletions common-content/en/module/decomposition/example-backend/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
+++
title = "Example backend"
headless = true
time = 30
facilitation = false
emoji= "📖"
objectives = [
"Run a backend using Express and NodeJS.",
]
+++

Here is a small backend written in JavaScript:

```js
import express from "express";

const app = express();
const port = 3000;

const quotes = [
{
quote: "Either write something worth reading or do something worth writing.",
author: "Benjamin Franklin",
},
{
quote: "I should have been more kind.",
author: "Clive James",
},
];

function pickRandomQuote() {
const index = Math.floor(Math.random() * quotes.length);
return quotes[index];
}

app.get("/", (req, res) => {
console.error("Received a request for a quote");
const quote = pickRandomQuote();
res.send(`"${quote.quote}" -${quote.author}`);
});

app.listen(port, () => {
console.error(`Quote server listening on port ${port}`);
});
```

If you save it in a file, make sure there's a `package.json` file in the same directory, `npm install express`, and run the file, it will start a server listening on TCP port 3000.

Express is a library which lets you listen for HTTP requests, and describe how you want to respond to them with callback functions.

Only two things in this file are new to us:

```js
app.listen(port, () => {
console.error(`Quote server listening on port ${port}`);
});
```

This code tells Express to listen for incoming HTTP requests on the port specified by the `port` variable (and also to log to stderr saying it's doing so).

```js
app.get("/", (req, res) => {
console.error("Received a request for a quote");
const quote = pickRandomQuote();
res.send(`"${quote.quote}" -${quote.author}`);
});
```

This code is instructing Express how to handle a request. It says "If you get a GET request for the path `/`, call this callback function".

What this callback function does is pick a random quote from an array, format it as a string, and send it as the body of an HTTP response. It also logs to stderr when it does this.

{{<note type="Exercise">}}
Run this code on your computer.

Open your web browser and visit http://127.0.0.1:3000

You should see a quote displayed.

Refresh the page a few times. You should see the quote isn't always the same.

Look at the stderr of your `node` process. What do you see?

Make sure you understand how your web browser is talking to your server, and why you're seeing what you see.
{{</note>}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
+++
title = "Limited cross-user interaction"
headless = true
time = 10
facilitation = false
emoji= "📖"
hide_from_overview = true
objectives = [
"Explain why sharing state across users may require us to write (or use) a backend.",
]
+++

We know if we want to share information between different computers, we need some backend to store that information so that the other computer can ask for it.

When we have multiple users, we have the same problem.

Imagine we're building a chat website, where multiple people can visit and talk with each other.

We couldn't build this if we only had a static frontend. When one user sends a message, other users wouldn't have any way of knowing it was sent. The message doesn't _go_ anywhere, it stays in the sender's browser.

If we want different users to be able to interact in any way, we need a backend they can interact through.

There are lots of examples of interaction, e.g.
* Live chat
* Seeing each other's posts
* Liking someone else's picture
* Seeing what someone else wrote in a list

All of these things require storing information from one user somewhere, so that another user can ask for it.

On websites, users don't interact directly with each other. They interact with a backend.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
+++
title = "Limited information"
headless = true
time = 20
facilitation = false
emoji= "📖"
hide_from_overview = true
objectives = [
"Identify strategies for updating information in a static website.",
"Explain why needing dynamic information may require us to write a backend.",
]
+++

{{<multiple-choice
question="What is a frontend?"
answers="Everything needed to make a website work. | The part of the website the user directly interacts with. | The part of a website that stores data."
feedback="No - a frontend is just one part of a website. Some websites only have a frontend, but many of other parts too. | Right! | No - The frontend is generally stateless (doesn't store data)."
correct="1" >}}

When we ask a server to serve us a static frontend, it can only give us the files it knows about.

Imagine we wanted to display the current weather in Rome on our website.

How could the server know that information? How could it give it to the user?

We know that our static frontend can only serve the files it knows about. So someone will need to save in a file on the server what the weather currently is.

There are a number of ways we could achieve this, e.g.:
* We could never update our file, and just serve out of date data.
* Someone with access to the server could connect to it and edit the file.
* We could set up some automated process which checks the weather, generates a new file, and uploads the new version to the server.

If we only host a static frontend, it is possible for us to update the information in it. But it is limiting.

Another approach, is that our frontend could know how to request information from a backend. That could be a backend we run, or one that someone else runs.

We have seen this when we have used `fetch`. `fetch` allows our static frontend to ask some other server for information.

We might not know whether the server we're asking for information is static or dynamic:

It could:
* Only serve information it already knows in its own files (i.e. it is a static frontend itself).
* Look up the information from a database which may change.
* Ask yet another server for information.

Even if we use `fetch` from our frontend, it is still a static frontend. We still serve it to users by giving them the same static files.

If someone else already runs a server we can `fetch` from, we can probably keep our own website just being a static frontend.

But if we need more dynamic information, and there isn't a convenient place we can fetch it from, we may need to write/host something we can `fetch` from ourselves. We call this a backend.

{{<multiple-choice
question="What is a backend?"
answers="Everything needed to make a website work. | A part of the website that we didn't write. | A part of the website the user doesn't directly interact with."
feedback="No - websites need frontends so that people can actually interact with them. | No - sometimes we may talk to a backend we didn't write, but this isn't always the case. | Right! A backend may supply information to a frontend, which will actually display it to the user."
correct="2" >}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
+++
title = "Limitations of frontends"
headless = true
time = 5
facilitation = false
emoji= "📖"
objectives = [
"Explain what can't be achieved with just a frontend",
]
+++

You've made static websites, both as part of the "world-wide web" reading, and in previous courses/modules.

These were HTML pages, which perhaps included some JavaScript. The JavaScript made them interactive. But they were still static.

A static website is one where your web browser requests some files from a server, and all the web server does is hand over the files.

From that point on, your web browser works on its own. Any event handlers, timers, etc are processed by the web browser.

And the job of the server was just to hand over files. Those files will probably be the same, no matter what user asked for them, or what computer they were using.

We often call these static files a **frontend**.

And we can build impressive, useful websites with just a frontend. We can include images, videos, and sounds. We can react to user input. We can change what we show on the page. We can even use things like [the Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API) to store data so that if you leave the page and come back, your data is still there.

But frontends also have limitations.

### Limitations of a frontend

Three major limitations of a website which only has a frontend are:
1. We only have access to information we knew when we made the frontend.
2. We can't share information across computers.
3. We can't interact with other users.

Let's talk about each of these.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
+++
title = "Limited sharing across computers"
headless = true
time = 20
facilitation = false
emoji= "📖"
hide_from_overview = true
objectives = [
"Explain why sharing state across computers may require us to write (or use) a backend.",
]
+++

The [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API) allows a website to store data so that if you leave a website, and go back to it, it remembers some things.

{{<multiple-choice
question="Where does the Web Storage API store data?"
answers="Locally in the web browser on the computer you're using. | On the website you're using, no matter what computer you're using. | It's synchronised with your email, so as long as you're logged in you can access it."
feedback="Right - Web Storage APIs just store information on your computer. | No - Check again. | No - Web Storage doesn't know anything about your email."
correct="0" >}}

A frontend has no way of bringing your data with you when you move between different computers.

Imagine you're using a to do list website on your computer, which only has a frontend. You add an item to the list. We can use the Web Storage API to make sure if you close the tab, and go back to the list, the item is still there.

But if you open the website on your phone, you won't see that item. Because the Web Storage API only stores the information locally in your web browser - on your computer.

This is one of the limitations of a static frontend - on its own, it can't share information across devices.

If we want to share information across devices, we'll need some backend to store that information, and share it.

One computer needs to tell the backend to store it, so that the other computer can ask the backend for the information.

We could write our own backend, or we could use an existing service like [Firebase](https://firebase.google.com/) which provides backends for things like authentication and data storage without us needing to run a backend ourselves.

But if we want to share information between devices, we need to use _some_ backend.

Any website that lets you log in will involve a backend.

{{<multiple-choice
question="If I'm using a website, and want to send a link to the page I'm viewing to a friend, does the website need a backend?"
answers="Yes - to be able to share the information between computers, it needs a backend. | No - a link will always work and show the same content. | It depends - on some websites links can work without a backend, but others need a backend."
feedback="Not always - if the website is just static, a link should work fine. | Sometimes! But only if the content it always the same for all users and a user can't change it. | Yes! Some websites are always the same for everyone, and links just work. Other websites, where users can change things (e.g. our to do list example), need some way of storing what things have changed, and this is normally a backend.<br /><br />Hint: If 'it depends' is a possible answer, it's _almost_ always the correct one!"
correct="2" >}}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
+++
title = "Read about the Internet"
headless = true
time = 30
time = 60
facilitation = false
emoji= "📖"
[objectives]
1="TODO"
objectives = [
"Define the terms 'host', 'client', and 'server'.",
"Define the terms 'request' and 'response'.",
"Explain the responsibilities/guarantees of four network layers: Link, Internet, Transport, Application.",
"Explain the purpose of a TCP port.",
]
+++

### Read about the Internet

Read chapter 11 of How Computers Really Work
{{<note type="Reading">}}
Read chapter 11 of How Computers Really Work.

Do every exercise listed in the chapters.

Do the following projects 29, 30, 31, 32, 34, 35.

For project 29, note that if you're on macOS, you should use `en0` not `eth0`, and you will need to install `arp-scan` by running `brew install arp-scan`.
{{</note>}}

Check you have achieved each learning objective listed on this page.

{{<multiple-choice
question="Which layer is responsible for retrying delivery of messages which didn't make it to a server?"
answers="Link | Internet | Transport | Application"
feedback="No - Link layer protocols may feature some local retries, but generally don't provide reliable delivery. | No - Internet layer protocols are typically responsible for routing, not reliable delivery. | Yes - the Transport layer is typically responsible for retrying delivery of lost messages, but not all Transport layer protocols support this. | Some applications do their own kind of retrying, but this is typically the primary responsibility of another layer."
correct="2" >}}

{{<multiple-choice
question="Which layer considers MAC addresses?"
answers="Link | Internet | Transport | Application"
feedback="Right - MAC addresses are how messages find their destinations on local networks. | No - the Internet layer typically uses Internet Protocol Addresses to navigate between networks. | No - the Transport layer typically deals with finding the right process on a host, rather than finding the right host. | Some applications may happen to deal with MAC addresses, but most applications do not. One layer (almost) always considers them."
correct="0" >}}

{{<multiple-choice
question="Which layer is responsible for ensuring that messages arrive at the server in the correct order?"
answers="Link | Internet | Transport | Application"
feedback="No - Link layer protocols typically don't guarantee ordered delivery. | No - Internet layer protocols are typically responsible for routing, not ordering. | Yes - the Transport layer is typically responsible for ordering of messages, but not all Transport layer protocols support this. | Some applications do their own kind of sequencing, but this is typically the primary responsibility of another layer."
correct="2" >}}

{{<multiple-choice
question="Which layer is used for getting from my home network to Microsoft's network?"
answers="Link | Internet | Transport | Application"
feedback="No - the Link layer is for messaging within local networks. | Yes - the Internet layer is for navigating between networks. | No - the Transport layer typically deals with finding the right process on a host, rather than finding the right host. | Some applications may happen to deal with routing information, but most applications do not. One layer (almost) always considers this."
correct="1" >}}
Loading

0 comments on commit 4026023

Please sign in to comment.