Usage
This service exposes several APIs, useful to upload, delete or download the files, described in details in the next paragraphs.
The routes can be prefixed by passing the --prefix option at startup.
Upload: POST /
With a multipart request containing the file to upload. The file will be stored on the configured backend, and the file information will be stored on MongoDB.
- single-bucket
- multi-bucket
Example of multipart request to upload a single file:
POST / HTTP/1.1
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
Content-Disposition: form-data; name="key-1"
Content-Type: text/plain
value-1
------WebKitFormBoundaryePkpFF7tjBAqx29L--
In case of a request to the Files Service with multiple bucket support, the name of the scope must be specified in the path of the request.
Example of multipart request to upload a single file with multiple-bucket support for the scope named scopeName
:
POST /scopeName/ HTTP/1.1
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
Content-Disposition: form-data; name="key-1"
Content-Type: text/plain
value-1
------WebKitFormBoundaryePkpFF7tjBAqx29L--
As it is possible to notice:
The first part is a
*.pdf
file namedmy-file-1.pdf
The second part is a plain text part with
name="key-1"
.
"key-1"
will be the key of a field that will be saved inside the file document infiles
collection."value-1"
will be the value of the that field.
Continuing the example above, once the file is stored, the respective document in the files
collection might be something like this:
{
//Basic file data
"_id" : "61c32e38e67eb6fc92ed50b9",
"name" : "my-file-1.pdf",
"file" : "078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"size" : 768,
"location" : "/v2/files/download/078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"__STATE__" : "PUBLIC",
"creatorId" : "public",
"updaterId" : "public",
//Specific metadata for the file
"key-1": "value-1"
}
In the example described above, to be able to upload the additional metadata key-1
, it is important to add a caster file and to specify its path in the environment variable ADDITIONAL_FUNCTION_CASTER_FILE_PATH
.
Without specifying a caster file, every additional metadata will be ignored.
At the moment, the file part must be the last one of the multipart. Any other part that follows the file part won't be considered.
This API supports only one file per request. If the request contains more files, then only the first one will be uploaded. Consider using POST /bulk
to upload multiple files at once.
Response
In case of success, the response is a JSON with the following fields.
- _id: unique MongoDB identifier.
- name: original file name.
- file: unique name of the file that should be used to retrieve it using this service.
- size: size in bytes of the uploaded file.
- location: the URL that can be used to download the file using the same service that performed the upload.
Upload many: POST /bulk
With a multipart/form-data
request containing all the files to upload and the respective metadata.
All the files will be stored on the configured backend, and the files information will be stored on the configured CRUD.
The order of the files inside the multipart is not important and files can have the same filename
field.
The upload of multiple files is handled as an atomic operation, meaning that either all files are stored correctly or none of them are.
- single-bucket
- multi-bucket
Consider the following simplified example of a HTTP multipart request:
POST /bulk HTTP/1.1
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
In case of a request to the Files Service with multiple bucket support, the name of the scope must be specified in the path of the request.
Consider the following simplified example of a HTTP multipart request with multiple-bucket support for the scope named scopeName
:
POST /scopeName/bulk HTTP/1.1
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
As it can be noticed, two files are being uploaded, both having the same filename
field set tofilename="my-file-1.pdf"
.
Apart from the multiple files, the multipart request accepts other parts useful to provide additional data to be saved the in the file document stored in the files
collection; please notice that these parts must have application/json
content-type.
In the following we describe with an example how to associate some structured metadata to a file
Consider the following example of multipart request:
POST /bulk HTTP/1.1
... other headers ...
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; filename="my-file-1.pdf"
Content-Type: application/pdf
... file content here ...
------WebKitFormBoundaryePkpFF7tjBAqx29L--
Content-Disposition: form-data; name="my-file1.pdf"
Content-Type: application/json
{
"anAdditionalProperty": "a_string_value",
"anotherAdditionalProperty": 34.12
}
------WebKitFormBoundaryePkpFF7tjBAqx29L--
As it is possible to notice:
The first part is a file named
my-file-1.pdf
.The second part is a text part of type
application/json
withname
whose value is the name of the file which will receive the metadata contained in the part.
Continuing the example above, once the file is stored, the respective document in the files
collection might be something like this:
{
//Basic file data
"_id" : "61c32e38e67eb6fc92ed50b9",
"name" : "my-file-1.pdf",
"file" : "078b04fa-6935-4686-ac5c-75f6b1ff5401.pdf",
"size" : 768,
"location" : "/v2/files/download/078b04fa-6935-4686-ac5c-75f6b1ff5401.pdf",
"__STATE__" : "PUBLIC",
"creatorId" : "public",
"updaterId" : "public",
//Specific metadata for the file
"anAdditionalProperty": "a_string_value",
"anotherAdditionalProperty": 34.12
}
Keep in mind the fact that File Service uses a CRUD service to store file documents in the files
collection, hence you'll need to register all the possible
keys that will be stored at the first level of the file document in the files
CRUD collection definition.
File info still pass through the function that the user can specify by means of the ADDITIONAL_FUNCTION_CASTER_FILE_PATH
environment variable before being passed to the CRUD service.
Response
At the moment, as stated earlier, the upload of multiple files at once is handled as an atomic operation, meaning that either all of the files are stored properly or none of them are.
In the case of success, a list with stored files' data is returned.
In the event of an error while storing one of the files, the service ensures that none file is stored, and an error is returned to the caller.
Continuing the last example of upload, in the case of success, the service answers with 200
and the following application/json
response:
[
{
"_id": "61c338e6e67eb6fc92ed50ba",
"name": "my-file-1.pdf",
"file": "02aa2106-661d-4fcc-9299-c72884ad0f28.pdf",
"size": 768,
"location": "/v2/files/download/02aa2106-661d-4fcc-9299-c72884ad0f28.pdf",
"anAdditionalProperty": "a_string_value",
"anotherAdditionalProperty": 34.12
}
]
Consider consulting the Open API definition of the service to get more information about the service responses.
Download: GET /download/:file
To download a single file that was previously uploaded, specifying its file
field.
Query parameters
download=1
: to download the file as an attachment.downloadWithOriginalName=1
: to download the file with its original name as attachment.useOriginalName=1
: to get the file with its original name.
The GET /download/:file
API, when used as link in the browser has different behaviors based on these query parameters; in particular with one of the download*
query parameters the file is downloaded as attachment. Instead, the use*
query parameter opens the requested file in the browser window.
This rule applies for all files except for HTML which are always downloaded preventing the browser from rendering them.
This API also supports a multi-bucket configuration. In this case, the scope parameter should be added to the path, to select the specific bucket instance on which to operate (GET /scopeValue/download/:file
, where scopeValue
is the name of the scope).
Download many: GET /download
To download a ZIP archive containing all the files specified in the query parameters.
Query parameters
files
required: array of strings (or single string) specifying thefile
field of the desired files to downloaddownloadWithOriginalName=1
: to download the files with their original names.
In case of a multiple-bucket files-service, the scope parameter should be added to the path to select the specific bucket instance on which to operate (GET /scopeValue/download
, where scopeValue
is the name of the scope).
Response
At the moment the download of multiple files is handled as an atomic operation, meaning that the API returns either all requested files in a (streamed) ZIP archive or an error.
Get files list: GET /files/
Get a list of files metadata managed by the Files Service in the bucket; the API supports pagination via query parameters.
Please note that this API is available from v2.7.0
Query parameters
limit
: integer value specifying the number of documents to be retrieved per request. Default to 25.page
: integer value representing the index of the requested page (starting from 1).dateFrom
: date value used to filter the files. Files older than this value will not be shown.
In the multi-bucket configuration, the scope parameter should be added to the path to select the specific bucket instance on which to operate (GET /scopeValue/files/
, where scopeValue
is the name of the scope).
Response
List of file metadata objects as retrieved from the Crud Service that match query parameters (if present).
Update file metadata: PATCH /:filename/metadata
This API allow to modify the metadata of a specific file. Only custom metadata fields, set with a caster file, can be modified.
Please note that this API is available from v2.10.0
The body must be a JSON containing the new values you want to set to the metadata.
The endpoint only modifies custom metadata fields defined in the caster file additionalPropertiesValidator
.
The other fields won't be modified, and silently ignored if added to the body.
Make sure to always specify all the metadata fields if you want to modify only some of them. Any field not specified may be removed.
In the multi-bucket configuration, the scope parameter should be added to the path to select the specific bucket instance on which to operate (PATCH /scopeValue/:filename/metadata
, where scopeValue
is the name of the scope).
Example
Consider a configuration with the following caster file:
'use strict'
module.exports = function caster(doc) {
return {
metadata: {
tags: (doc.tags || '').split(','),
authorId: doc.authorId || undefined,
ownerId: doc.ownerId || undefined,
}
}
}
module.exports.additionalPropertiesValidator = {
tags: { type: 'string' },
authorId: { type: 'string' },
ownerId: { type: 'string' },
}
The collection contains this document:
{
"_id" : "61c32e38e67eb6fc92ed50b9",
"name" : "my-file-1.pdf",
"file" : "078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"size" : 768,
"location" : "/v2/files/download/078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"__STATE__" : "PUBLIC",
"creatorId" : "public",
"updaterId" : "public",
"metadata": {
"authorId": "someOldVal",
"ownerId": "someOtherOldVal",
"tags": "some,tags"
}
}
You can update the authorId
and the ownerId
with the following http call:
curl http://my-files-service/filesMetadata \
-X PATCH \
-raw-data '{
"authorId": "someNewValue",
"ownerId": "someOtherNewValue"
}'
In this case, the object returned by the caster function will replace the specified metadata
CRUD field. For this reason, any field not specified in the body will be undefined in the resulting document.
The endpoint will return 204 No Content
in case of successful operation.
This is the resulting document after the PATCH:
{
"_id" : "61c32e38e67eb6fc92ed50b9",
"name" : "my-file-1.pdf",
"file" : "078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"size" : 768,
"location" : "/v2/files/download/078b04fa-6935-4686-ac5c-75f6b1ff5401.txt",
"__STATE__" : "PUBLIC",
"creatorId" : "public",
"updaterId" : "public",
"metadata": {
"authorId": "someNewValue",
"ownerId": "someOtherNewValue"
}
}
Response
List of file metadata objects as retrieved from the Crud Service that match query parameters (if present).
Delete: DELETE /:file
To delete a file that was previously uploaded.
In the multi-bucket configuration, the scope parameter should be added to the path to select the specific bucket instance on which to operate (DELETE /scopeValue/:file
, where scopeValue
is the name of the scope).