Project Background
This project can be using in an existing app that has an Express backend file server or it can act as a standalone file server. It's designed for use with standard ISoft-style-application MYSQL schema(SELECTs from file and filechunk tables).
Installing
npm i @isoftdata/file-service
Getting Started
This project is designed with two use cases in mind:
For Use in a Project with an Existing Web Server
API
@isoftdata/file-service exports an object with a registerFileServiceRoute function on it. That function takes the an object with the following shape:
| webServer | Object | Must be an express server instance | N/A - Prop is Required |
| connection | Object | Must be one of mysql's Pool, Connection, or PoolConnection classes | N/A - Prop is Required |
| routePrefix | String | The HTTP route from which the image(s) will be served | /** |
connection Tip: if you give a Pool class for the connection, a single connection will be pulled from the pool for each individual request and released at the end of that request. The connection won't be released if you pass a PoolConnection or Connection(of course).
routePrefix Tip: if you want to serve images from the root of the web server, give an empty string for routePrefix.
Example usage:
import express from 'express'
import fileUpload from 'express-fileupload'
import mysql from 'mysql'
import { registerFileServiceRoute } from '@isoftdata/file-service'
const expressServer = express()
const port = process.env.PORT ?? 80
const pool = mysql.createPool({
host: 'example.org',
user: 'bob',
password: 'secret',
database: 'my_db',
})
expressServer.use(fileUpload())
registerFileServiceRoute({ webServer: expressServer, connection: pool })
expressServer.listen({ port }, () => console.log(`🚀 Server ready on port ${port}!`))
As a Standalone Web Server
- Clone this repository
- Run
npm i
- Create a
.env file in the root of the project that looks like this, but with valid values filled out:
MYSQL_HOST=
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_DATABASE=
PORT=
The web server will accept requests to any path so long as the path ends in <md5-checksum-of-the-file><file-id>/<file-name>.
In other words, foo/bar/baz/fd90a7512022dd825fcd41982ec466931956/mySweetPicture.jpg is just as valid and the same as images/fd90a7512022dd825fcd41982ec466931956/mySweetPicture.jpg.
Request Parameters
When making a request for an image, a few GET parameters are available(all optional):
width
height
background (defaults to 255)
fit
These parameters, if valid, are passed into the Sharp image processor. For details on these parameters, check out the Sharp resize docs.
Using the Client
The FileServiceClient class is exported by this module and can be used to upload images. Example usage:
import { FileServiceClient } from '@isoftdata/file-service'
import fs from "fs"
const client = new FileServiceClient({
maxImageHeight: 1024,
maxImageWidth: 1024,
url: 'http://localhost:4000',
})
client.addFile({
name: 'myFile.jpg',
stream: fs.createReadStream('./myFile.jpg'),
})
client.addFile({
stream: anyReadableStream,
})
const resultsPromise = client.upload()
What about authentication?
The file service doesn't have any concept or opinions about authentication requirements baked in. If you want to ensure that your files can't be accessed by someone that could guess the MD5 hash + fileid combo, we recommend you write an authentication checking middleware function that you register before the file service. Something like this:
const express = require('express')
const expressServer = express()
const cookieParser = require('cookie-parser')
expressServer.use(cookieParser())
expressServer.use('/files', async(req, res, next) => {
const authenticated = await isAuthenticated(req.cookies.token)
if(!authenticated) {
next(new Error('Not Authenticated'))
} else {
next()
}
})
where the isAuthenticated function is from your app and knows how to check if a session is valid/authenticated.
What schema is required?
Some common ISoft schema is expected:
Tables:
Functions:
Breaking changes
Version 3
The only breaking change from version 2 to 3 was the requirement of Node 16
Version 4
Removed opinion of the File service that only images can be uploaded using the imported File Service functions.
*Chunker chunks files properly