Our Web Framework so far can create a REST API, but cannot serve files yet, we need to implement it to make the framework complete.
To serve files we are going to use the Streams concept to read the files and serve to the client.
If you want to know more about NodeJS Streams take a look at it here
Let's go!
Reading files and folders
src/app.js
// (1)
const { readdir } = require('fs/promises')
const { statSync, createReadStream } = require('fs')
const path = require('path')
const { pipeline } = require('stream/promises')
// (2)
async function* getAllStaticFiles(folder) {
const files = await readdir(folder)
for (const file of files) {
const absolutePath = path.join(folder, file)
if (statSync(absolutePath).isDirectory()) {
yield* getAllStaticFiles(absolutePath)
}
else {
yield absolutePath
}
}
}
// (3)
const static = async (folderPath) => {
let folderRelative = folderPath.replace('./', '')
for await (const file of getAllStaticFiles(folderPath)) {
const pathWithoutBase = file.replace(folderRelative, '')
get(pathWithoutBase, async (req, res) => {
const relativePath = path.join(__dirname, '..', file)
const fileStream = createReadStream(relativePath)
res.setHeader('Content-Type', file.split('.').filter(Boolean).slice(1).join('.'))
return await pipeline(fileStream, res)
})
}
}
// (4)
return {
run,
get,
post,
patch,
put,
del,
use,
useAll,
useRouter,
static
}
From the code sessions above
1 - To read files and folders and deal with Streams we need to import fs
and stream
libraries.
2 - Here we are reading files and folders' paths recursively using a generator pattern to make the reader be ordered.
3 - For each file path found we are going create a new GET route, read the file path as a Stream
, and pass the Stream
to the response
object. If you didn't know the response
object is a Writable Stream
.
4 - Exporting the static
function.
Testing
Now we can call the static
function passing the folder path that contains the files we want to serve.
index.js
app.static('./files')
const start = async () => {
app.run(3000)
}
start()
To test I will create a folder structure with a file like that.
files/folder1/file.json
{
"test": "test"
}
If I run the app and try to access the path localhost:3000/folder1/file.json
, I can see the content inside it.
You can see herehow the code is looking.
See you in the next tutorial to improve our Web Framework, we are going to create a body-parser middleware.
I hope you like it!
Top comments (2)
wow can't wait for next part!!!!
new tutorial
dev.to/wesleymreng7/creating-your-...