No assignment this week; enjoy your break!
From now on, we will be using a
tsconfig.json file within every Node project
we create (a recap on how to do that is below this section). Essentially, the
tsconfig.json is a file at the root of a Node project which indicates it is using TypeScript, and allows us to configure the TypeScript compiler. If you're more curious about how the file works, you can refer to this link.
Let's dive deeper into what happens when you setup a Node project using Yarn.
Navigate to an empty folder where you want your project to be located. I will assume this folder is called
yarn init in this folder on the terminal. (Use
cd to navigate to you
helloworld folder in terminal)
Note that we are using
yarn init rather than
npm init. We will be using Yarn as our
Node package manager in its class (this is used in production at many companies like Facebook!), and its corresponding commands for installing packages as well.
yarn init, and answering the questions as seen in the previous lecture, we now need to add our dependencies for the project and scripts to start it.
Node projects don't come with every possible dependency right out of the box. We
will add these with Yarn by using
yarn add <pkg_name> (which is the equivalent
npm install <pkg_name> --save, but remember we are using Yarn.)
Let's try installing a package. In the first assignment we asked you to use
express by running:
yarn add express
After installation completes, take a look at your
package.json. We named our project "test".
express was added to our dependencies. Now
express is available for you to use in your project!
Every time you add a dependency with
yarn add <pkg_name>,
<pkg_name> will be added to your dependencies in
package.json if it can be found. It will also be added to
Take a look inside your
node_modules folder. This is where all your packages will be installed. Notice that even though you just installed one package, multiple packages are in
package.json. This is because
express itself has several of its own dependencies that also got installed.
You might see red squiggly lines when working with TypeScript files about missing
"declaration files". This means you need to install the corresponding type packages
for each dependency you work with in TypeScript, as it gives you some predefined
type definitions to work with, which makes your life easier! You can install these
yarn add @types/<pkg_name>
You can find more packages to use on npmjs.com.
node_modules can potentially hundreds of megabytes of data on packages you installed. It is important to never submit this with your assignment or push it up to any remote repositories such as GitHub. Before submitting an assignment, remember to remove
node_modules from the folder, then zip it and submit the zip file. You will be penalized if
node_modules is submitted. Don't worry, we will be able to recover your dependencies simply by running
Let's say you made a typo installing
express and you instead ran
yarn add experss
package.json should look like this:
Unfortunately, some malicious developer capitalized on this typo mistake and made
experss an actual package. How do you remove experss?
There are two ways. First, you can just run
yarn remove experss. This will remove
experss from your
package.json and your
Another way is to delete
experss manually from your
package.json. (Just delete the line that has
experss). This won't actually get rid of the package from your
To update your
node_modules, first delete your
node_modules folder and then run
This fetches all your dependencies again based on your
package.json and since
experss is no longer there, it is not installed.
Let's go more in-depth with using Express with HTTP methods beyond
GET, TypeScript types, and request bodies.
We'll also introduce a tool called Postman, which makes it much easier to playtest our backend endpoints.
Say we're making some API endpoints for a music streaming service. Each song has its own name and a rating. We want to be able to access all the songs through a
GET endpoint, add new songs through a
POST endpoint, update ratings through a
POST endpoint, and remove a certain song by its name using a
Before we begin, make sure to put the
tsconfig.json file with the contents at the top of this page in the root of your Node project folder.
As described earlier in this lecture, let's do a standard
yarn init and answer the questions accordingly. In the same directory, let's install dependencies with the following commands we need to develop this Express and TypeScript project:
yarn add express
yarn add typescript @types/node @types/express --dev
We install TypeScript and the type definitions for Node.js and Express as dev dependencies because we are not exporting them, but simply using them in our
Let's go back to
package.json for a moment in order to set up a script to run
our Express web server. It should currently look like this:
Let's add a
script field with two commands: one to compile our TypeScript file for the server, and one to compile and run the server using Node. You can update the
package.json to include a script with these commands:
You can run each of these scripts using
yarn tsc and
yarn start. None of these commands should work yet though, since we haven't even started writing
Note that you can name these scripts whatever you want: for example, you could have called
"pizza" and used
yarn pizza. Also,
yarn start first runs
yarn tsc (through the use of the
&&), and if this passes without error, we then run
node output/index on the JS file produced by the TypeScript compiler to launch the server.
Create a new file called
index.ts (note the
.js, but remember we're using TypeScript) and add the following:
Much of this should be familiar. The first line loads in the
express dependency and the second line initializes
app.use(express.json()) allows us to make use of request body parsing in Express
later (in the
/addSong endpoint). Don't worry too much about what exactly this does,
but feel free to search and learn more.
songtype type definition allows us to outline what we expect the metadata for
each song in the system should be. This is our first powerful use of TypeScript in
web development: if data doesn't conform to this spec, we'll immediately know since
TypeScript's compiler will give an error, saving us a lot of debug time and headaches.
app.get specifies that any
GET requests sent to the endpoint
/getSongs will send back the array of songs, which is initially the empty array
app.listen starts the server on port 8080 asking it to listen for requests.
Let's test these endpoints by running
App started! should be printed on the terminal showing that the port is up and running and listening for requests.
Use your web browser to navigate to
localhost:8080/getSongs. You should see the value of
songs, the empty array
, on the page.
You can terminate the running of the script using Ctrl + C.
Instead of always going to the endpoint in the browser, a robust way of testing our endpoints is to use Postman.
Postman is a software that allows you to simulate requests that could be sent by a user to your backend. It is useful for testing and ensuring that the behavior of your requests (including necessary headers) is what you expect.
Download Postman here.
Once you have Postman set up, make a request to the
/getSongs endpoint by setting the request type as
GET and the url as
localhost:8080/getSongs. You should see
 in the response body.
Usually when you want to send a
POST request you also want to send information with it. Situationally, you want to do this using request bodies rather than query parameters.
Add the following to your
index.ts file after your
Previously, we may have considered using query parameters for sending data for the backend. There's nothing wrong with that; we could have used
/addSong?name=Despacito&rating=5. However, this can lead to extremely long URLs, and limit us from sending more complicated data. That's where request bodies come in handy. We can instead send request data in JSON format to the backend, allowing us to use the data more easily and integrate it seamlessly with our backend (which happens to be in TypeScript, so we can easily deal with it).
express to listen for
POST requests at endpoint
req.body is a JS object, and we access its properties
req.body.rating to add a new song to our array of songs. We also make sure that this is compatible with a
songtype: after all, the rating of a song can't be a word, and the TypeScript compiler will yell at us if we mess this up!
However, we can't test request bodies quite as easily through the browser; we can check that this endpoint is working using Postman. Set the request type to
POST and URL as
localhost:8080/addSong. To send a request body, first go to Headers and add a new key
Content-Type with value
application/json. This says we are sending JSON input (essentially, an object or dictionary) in our request body. In the Body section, select the raw radio button and enter the following in the text field:
We will be sending
name with a value of
rating with a value of
5 in the request body.
Sending this request, you should see the corresponding song printed out to the console by the endpoint.
Now, let's create another
POST endpoint to update a song's rating. This will also use a request body with just a
name field, which should match the song we want to update.
When creating APIs, we use the
DELETE request method to quite simply delete a specific resource. This should be pretty straightforward: we simply take the name of the song to delete through the request body, and create a new version of the songs without the specified song. We then send text to the requester that it was deleted.
And with that, we're done!
The music streaming API we just made "works": we can add songs and then get them while running the Express server. But it has one fatal flaw: try stopping the server and then running it again. You'll see that all the music is gone! We need some kind of persistent storage for this data: through—you guessed it—a database.
- Data stored within Node.js is per instance
- Most applications require persistence
- Data analysis
- Performant data location
- Offloading unneeded data from memory
- Stores data in tables, utilizing rows and tables.
- Is relational (think a tuple)
- Has a schema
We will focus on NoSQL
- Many NoSQL implementations are schema-less or have a partial schema
- Firestore is a cloud-hosted NoSQL database
- Very flexible and can be used with most popular languages
- Uses documents to store data
- Efficient querying for data
- SQL databases have a predefined schema, whereas NoSQL databases can abide to any structure you want it to.
- NoSQL databases are better suited for large sets of data, but not for complex queries.
- SQL databases tend to be less expensive for smaller datasets, but also less flexible.
- SQL has strong consistency whereas NoSQL has eventual consistency (i.e. there may be some delay in getting the response back)
- SQL is vertically scalable (need more computing power on one machine to store more data) while NoSQL is horizontally scalable (can distribute storage and compute power on multiple machines)
- Firebase is a Backend as a Service (BaaS) offered by Google
- Allows you to store data
- Host websites
- NoSQL DB
- Not only SQL
- Non relational
- Real-time operations
- Firebase Authentication
- Built-in analytics
- Also supports hosting/deployment
- Integration with other Google services
- Structure we’re familiar with!