A Meteor library to make file uploading and managing as easy as possible. It offers a consistent and resilient file storage strategy, relying on busboy, mongodb and gridFS. The files are stored in MongoDB. The package is very lightweight (~25kB minified) and has only busboy as direct dependency.
Installations
npm install meteor-mongo-files
Developer Guide
Typescript
No
Module System
ESM
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (100%)
Developer
jonisapp
Download Statistics
Total Downloads
1,498
Last Day
2
Last Week
8
Last Month
43
Last Year
213
GitHub Statistics
3 Commits
1 Watching
1 Branches
1 Contributors
Bundle Size
26.01 kB
Minified
6.45 kB
Minified + Gzipped
Package Meta Information
Latest Version
0.1.11
Package Id
meteor-mongo-files@0.1.11
Unpacked Size
40.50 kB
Size
12.38 kB
File Count
8
Total Downloads
Cumulative downloads
Total Downloads
1,498
Last day
100%
2
Compared to previous day
Last week
-50%
8
Compared to previous week
Last month
975%
43
Compared to previous month
Last year
-46.5%
213
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
1
Dev Dependencies
4
meteor-mongo-files
Introduction
A Meteor library to make file uploading and managing as easy as possible. It offers a consistent and resilient file storage strategy, relying on busboy, mongodb and gridFS. The files are stored in MongoDB. The package is very lightweight (~25kB minified) and has only busboy as direct dependency.
What problem does it aim to solve ?
Keeping consistency in a file management system is not an easy task. Why not integrate the files directly with the rest of the data ? Considering the Meteor ecosystem, there is currently only one well-maintained library for online file storage and management : Meteor-files. I have used it for different projects and I must say that it works like a charm. Meteor-Mongo-Files is not intended to replace it but to meet different needs. The main goal is to reduce complexity to a minimum. By focusing exclusively on MongoDB, one sacrifices the flexibility that a library such as Meteor-Files can offer, but with the advantage of providing an equally powerful set of features and no boilerplate.
Benefits
- keep all your data in one place
- is capable of incredible scaling
- If your application is on the same network as your database, latency will be lower than with a remote storage solution like AWS S3.
- It will lower data transfer costs if you use a self-managed MongoDB instance.
Drawbacks
- It will increase overall costs if you use a managed DBaaS like Atlas.)
- If you deal with a lot of big files, it will not perform as well as object storage.
One library : 2 strategies
Files can either be stored in their entirety (as MongoDB documents) or chunked by GridFS. In this second case, GridFS creates 2 collections: "collection.files" and "collection.chunks", which makes it possible to reconstitute the files. Let's evaluate which approach is better for your use case. Using one document per file seems simpler, but it also has a few disadvantages:
- a MongoDB document is limited to 16Mb
- if you store a file directly as a document, it cannot be streamed directly to the database. Hence the file will be temporarily loaded entirely into the memory which may lead to a decrease in overall performance.
So this approach is generally preferred if you have a lot of small files or if you need low latency (even if it means increasing performance costs)
And when it comes to GridFS, you can store files of unlimited size and files can be directly streamed from the DB to the client, but:
- it will use more storage because additional information is stored within each chunk
- it will need more processing power.
So this approach is generally preferred if you have fewer but larger files
Install
1npm install --save meteor-mongo-files
Simple usage (CRUD)
1// anywhere in Meteor server
2
3import { WebApp } from 'meteor/webapp';
4import { meteorMongoFiles, Buckets } from 'meteor-mongo-files';
5
6const [parseDocumentData, downloadDocument] = meteorMongoFiles({
7 bucketName: 'documents', // as you can see, most of the configuration is done internally.
8});
9
10WebApp.connectHandlers.use('/api/documents', async (req, res, next) => {
11 switch (req.method) {
12 case 'POST':
13
14 const saveDocumentToDB = await parseDocumentData(req);
15 await saveDocumentToDB(/* custom file name and metadata */);
16
17 res.writeHead(201); /* we respond with a 201 http code (created) */
18 res.end(); break;
19
20 case 'GET':
21
22 downloadDocument(req, res); break; /* downloadDocument is in charge of the http response */
23
24 case 'PATCH':
25
26 Buckets.documents.rename(req.body.id, req.body.new_name);
27 res.writeHead(204)
28 res.end(); break;
29
30 case 'DELETE'
31
32 Buckets.documents.delete(req.body.id); // where "documents" is our bucket name
33 res.writeHead(204)
34 res.end(); break;
35 }
36});
As you may have noticed, for renaming and deleting we can directly rely on GridFSBucket.
Options
meteorMongoFiles(options)
Attribute | Type | Default value | Description |
---|---|---|---|
BucketName | string | 'documents' | name of the bucket/collection that MeteorMongoFiles will create |
gridFS | boolean | true | defines whether GridFS engine will be used or not |
db | Db (MongoDB native) | default Meteor MongoDB instance | MongoDB instance |
generateFileId | function | Random.id() | a function to generate a custom MongoDB _id |
Example of requests
1// POST 2const formData = new FormData(); 3formData.append('ressource_id', data._id); 4formData.append('ressource_type', 'contact'); 5formData.append('file', file); 6formData.append('filename', file.name); // filename is sent separately because utf-8 encoding will be lost 7 8await axios.post('/api/documents', formData);
GET requests are based on 2 query params: id
and download
1// GET 2const res = await axios.get( 3 `/api/documents?id=${fileId}&download=false`), 4);
If download query param is true, it will trigger a download. If not, the file will be opened in the browser (provided that its format is supported). This parameter actually determines the Content-Disposition header of the response.
1<!-- inline --> 2<img 3 src="https://yourwebsite.domain/api/documents?id=FpPJxvmN8gDnKSiqp&download=false" 4/> 5 6<!-- download --> 7<a 8 href="https://yourwebsite.domain/api/documents?id=FpPJxvmN8gDnKSiqp&download=true" 9 >Download</a 10>
Take advantage of Meteor's reactivity
When you create a GridFS bucket (see the example above) it also creates 2 MongoDB collections (if GridFS is enabled) or juste one (if disabled). In the case of our previous example, 2 collections were created: "documents.files" and "documents.chunks". These collections can be used as usual within Meteor.
GridFS enabled
1const Documents = new Mongo.Collection('documents.files');
2
3Meteor.publish('documents.files', function () {
4 return Documents.find({});
5});
GridFS disabled
With GridFS disabled, the only collection get the same name as the bucket. There is one particularity that requires our attention in this case: the MongoDB document has a field which holds all the file's data. Hence, for a reason that seems fairly obvious, the "data" field must be excluded from our publication.
1const Documents = new Mongo.Collection('documents'); 2 3Meteor.publish('documents', function () { 4 return Documents.find({}, { fields: { data: 0 } }); 5});
The whole picture (GridFS enabled)
License
MIT © jonisapp
No vulnerabilities found.
No security vulnerabilities found.
Gathering detailed insights and metrics for meteor-mongo-files