The Backend Service
Welcome Back! Please read through Part 1 if you haven't already. Now, let's dive into Part 2: Building the backend service for our web3 movie streaming platform.
We've provided a starter code for the backend, which currently displays a "Welcome" message when you start the server and visit http://localhost:9000
in your browser. Let's build on this foundation.
We currently have these codes in the source directory of the backend, and let me briefly explain them to you.
Utility Files
This folder which can be fully addressed to backend/src/utils
contains two essential files, an HTTP exception handler function and an interface for handling file upload information.
This code defines a custom HttpException
class that extends the built-in JavaScript Error
class, allowing for the creation of error instances with specific HTTP status codes and messages.
This code defines an interface FileUpload
that represents an uploaded file, specifying its properties such as name, data, size, encoding, and more, providing a structured way to handle file uploads in this backend application.
And then at backend/src
root folder, we have this index.ts
file which sets up an Express.js server with CORS and file upload support, defines a single GET route that returns a "Welcome" message, and handles errors by catching and re-throwing them as custom HttpExceptions, then starts the server on the port 9000 as specified in the environment variables.
Now that we've covered the key files, let's create two new files in a services
folder, each serving a distinct purpose in our application.
Service Files
In the backend/src
folder, make a new folder called services
in this location, this is where we'll create two services:
- Sia Service: Handles file uploads, downloads, streaming, and caching, communicating with the Renterd service.
- Background Service: Manages cached files, automatically removing them after 7 days at midnight daily.
The Sia Service
Let’s create a file named sia.service.ts
at the backend/src/services
folder and follow the steps below to formulate this service.
This code defines a SiaService
class that initializes with environment variables for Sia API settings and an origin URL, providing a foundation for managing interactions with the Sia service. Now, let's supply the rest of the codes for this service.
Uploading Files to Sia Renterd
To upload files to the Sia Network, we will need to add these three methods into the class, two will be private whereas one will be public.
This code defines a private method generateRandomString
that generates a random string of a specified length, composed of uppercase and lowercase letters and numbers, using a loop to select characters randomly from a predefined string. We will use it to rename each file uniquely before shipping a file to Renterd.
The above code defines a private method uploadToSiaService
that uploads a file to Sia Renterd using Axios, handling upload progress and errors, and returning the Axios response or throwing an error if the upload fails.
The Renterd endpoints are written in the API documentation which you can check out or watch the video below where I explained how the Sia Renterd API documentation.
Now let’s include the public method which we will later expose as an endpoint in our application.
This code defines a public method uploadFile
that uploads a file by generating a unique identifier, saving the file to a local cache, and then uploading it to the Sia Renterd, returning the file's URL and a success message or throwing an error if the upload fails.
Downloading Files to Sia Renterd
To download files to the Sia Network, we will need to add these two methods into the class, one will be private and the other will be public.
This code defines a private method downloadFromSiaService
that retrieves a file from the Sia service, caches it locally, and returns a readable stream of the file, handling errors and returning a 404 image if the file is not found.
Let’s have those response_files available in the backend directory, else we will experience an error calling the 404.png
file. At the backend
directory create another folder called response_files
and copy the following images into it.
Perfect, now let’s complete this file download service, also add the method below in the SiaService
class.
This code defines a public method downloadFile
that calls the private method downloadFromSiaService
to retrieve a file from the Sia Renterd and returns the readable stream of the retrieved file.
Service Endpoints
It's time we couple these various methods to their respective endpoints, currently, we have just one, but we will need an additional two for uploading and downloading files. File streaming will also utilize the download endpoint.
Head to the backend/src/index.ts
file and update its content with these codes.
This code sets up an Express.js server with CORS and file upload support, defining three endpoints: a welcome message, file upload to the Sia Network, and file download from the Sia Network, using the SiaService class to handle file operations and HttpException for error handling.
Watch this section of the video below if you require some visual aid, ensure you stop at the 01:50:44 timestamp.
We need to create a cache management service to ensure our server doesn't fill up with unused files by controlling how long files stay in the cache. Its important to know that the only reason we needed this service is to reduce data latency.
The Background Service
Head to the backend/src/services
folder and create a file called background.service.ts
and add these sequences of code to it.
This code defines a BackgroundService
class that sets up a cache directory and schedules daily jobs using the node-cron
library, initializing the background jobs and logging a confirmation message. Let’s create a method that will be responsible for deleting files older than 7 days in the cache.
Deleting Old File
Add this method to the BackgroundService
class.
This code defines a method called deleteOldFiles
that removes files from a cache directory that are older than 7 days, by reading the directory, checking each file's creation time, removing files that exceed the target time, logging the start and end of the job, and any errors or successful deletions.
Now, let’s write a function that will utilize the node-cron package to schedule when to execute the file deletion.
This code sets up a daily cron job to run the deleteOldFiles
method every day at midnight (00:00) to perform automatic file cleanup.
We also need to update the constructor function to schedule the daily Jobs at the instantiation of the background service class.
Perfect, lastly, let’s add this background operation as part of the server process at initialization. Head to the backend/src/index.ts
file and update the app listener method and also importing the background service file.
You should rerun the backend service command using $ yarn build && yarn start
and see a terminal printout like the one in the image below.
If you would rather watch how I coded the entire background service, the video below is for you, just ensure you stop at the 02:16:07 timestamp.
Next Step
Congratulations, you are now ready for the final part of this tutorial which is Part 3. If you encounter any issues, refer to the following resources for troubleshooting.
About Author
I am a web3 developer and the founder of Dapp Mentors, a company that helps businesses and individuals build and launch decentralized applications. I have over 8 years of experience in the software industry, and I am passionate about using blockchain technology to create new and innovative applications. I run a YouTube channel called Dapp Mentors where I share tutorials and tips on web3 development, and I regularly post articles online about the latest trends in the blockchain space.
Top comments (0)