Storage service
A dedicated service for managing files.
A service for the purpose of managing files may prove quite useful. What we'll first do then is to generate a files module and a storage service.
The overall structure was inspired by this article from Prateek Kathal (blog).
Here, we'll adopt an ideia similar to the HashingService
. That is, to have an abstract class with the methods' signatures and a concrete class with their respective implementations. So, in the StorageService
, we should have signatures to:
Save a file
Create a directory
Get a file
Get the names of files inside a directory
Calculate the amount of files inside a directory
Delete a file or directory
Validate a path
Each method will be better detailed during its implementation. Therefore, let's proceed to implement the concrete class.
Node.js, by default, has the fs module for managing files. However, the fs-extra package has the same functionalities and more features/improvements. It's already installed, so let's just add its typing.
Now, we can create a concrete service that implements the methods of the StorageService
using fs-extra. After creating it, we should make it implement the StorageService
.
Let's also already adjust the providers
in the FilesModule
. Remember to add the StorageService
to the exports
.
In file.constants, let's define a constant for the base directory where all the files will be stored, which will be the upload folder at the root of the project.
Also add this folder in the .gitignore file, as we won't publish files to the code repository.
Let's then, finally, implement each one of the methods in the FseService
.
saveFile()
- Receives thepath
and thefile
, and then saves it in thispath
prepended with theBASE_PATH
, with the file'soriginalname
, from itsbuffer
createDir()
- The functionmkdirp()
allows to create folders and even nested ones
getFile()
- This function returns the file as aStreamableFile
, which allows for more flexibility
This NestJS doc further explains the class mentioned above.
getDirFilenames()
- Obtains the names of files inside a folder
getDirFilecount()
- Counts how many files are inside a folder, using the previous method
delete()
- Deletes a file or folder
validatePath()
- Checks if apath
exists, throwing an exception if it does not
And we're done! We now have a quite interesting set of util functions to aid us when managing files.
Commit - Implementing file storage functions
Before finishing the StorageService
, let's just add two more methods there. We may then write methods' signatures to:
Validate the amount of files to be saved into a directory
Generate a unique filename from the original one
And now, in the FseService
, implement them.
validateFilecount()
- Checks if the file count exceeds a maximum
genUniqueFilename()
- Prepends a filename with a unique prefix
The unique prefix was obtained from the Multer docs.
Lastly, adjust the saveFile()
method to use the unique filename.
Commit - Some more features in file storage
Last updated