Painless file upload using FeathersJs service

Rowadz
4 min readMar 29, 2019

--

In this article, I aim to show a way to upload files using feathers service, and by the end, we can still use it as a normal feathers service.

  • I will be using MySQL and Sequelize ( But this will not affect anything ).

I’m starting from the beginning by generating a new feathers application using the CLI.

Then I will generate authentication using the CLI, which will create a users service, and generate a hook and express middleware for authentication.

Now we can start with the uploads service by :

  • Generating it.
  • Modifying the model.
  • Install multer & Modifying the service to make it handle file uploads and still behave normally.

Generating the uploads service :

Modifying the model:

I think the model is self-explanatory.

Install Multer & Modifying the service:

  • You can install Multer by typing npm i multer into the root of your project.
  • I will store the uploaded files in a folder called uploads inside the public folder.

The service after modifying it, with comments to help you understand the changes.

Usage :

  • First I will create a user ( because we added the auth middleware ) :
curl 'http://localhost:3030/users/' -H 'Content-Type: application/json' --data-binary '{ "email": "test@test.test", "password": "secret" }'
  • to authenticate the user :
curl 'http://localhost:3030/authentication/' -H 'Content-Type: application/json' --data-binary '{ "strategy": "local", "email": "test@test.test", "password": "secret" }'

this will give us the user’s accessToken which we will use with the files to authorize the user

  • Uploading files ( using postman ) :
notice the key of the images is `files` which is the same string we passed to the multer middleware!, `upload.array(‘files’)`.
  • Without the jwt token, the files will not be stored!
  • with jwt, the response looks like this:
Adding the same `description` to the images is redundant, but it’s just to show an example, this might be a post_id or something like this.
  • Note that the service still behaves normally, if we tried to see the data via HTTP GET request we can:

trying to modify the image with id 1:

we can update, patch, delete, get, post using this service. However the files you uploaded still need to be removed in some time, you can do that with more hooks or by a cron jobs.

If you want to filter the file based on the extension, you can register a fileFilter using multer, I highly recommend you to read Multer’s documentation.

Notes :

  • The only line that is needed is a req.feathers.files = req.files In the middleware, we added before creating the uploads service, which transfers the files into feathers and the code that shapes the data into the model format should be a before create hook and before patch hook.

Another Approach: Express middleware.

We can create a normal express middleware that only handles files and returns their id after inserting the path of each file into a table.

let’s start by generating a service called media.

  • the media model ( just storing the path and Sequelize will add the id, createdAt, updatedAt ).

now we need to generate the middleware and handle files:

generating the middleware with a path `media-upload`

go to src/middleware/index.js and add the following code :

and in the my-uploadmiddleware add the following code

To test the middleware :

The response :

Now you can use the returned id to link the media with any other table, this will be really useful when you don’t want to send a large request, but you will send the files when the user adds them and send only their id with the main request.

END

Hopefully, this was useful to you 🙂.

useful links

1 — About multi: true here.

2 — Feathers file upload docs here.

3 — a video which might be helpful

--

--