.. _tutorial-attachments:
Work with Attachments
=====================
Goals
-----
* Publish large or binary content
Prerequisites
-------------
This guide assumes that you have already installed the following commands:
- cURL
- uuidgen
- `jq `_ (*optional*)
And that you are familiar with the Remote Settings API, at least on the dev server.
We'll refer the running instance as ``$SERVER`` (eg. ``https://kinto.dev.mozaws.net/v1``).
Introduction
------------
Files can be attached to records. When a record has a file attached to it, it has an ``attachment`` attribute, which contains the file related information (url, hash, size, mimetype, etc.).
The Remote Settings client API is **not in charge** of downloading the remote files during synchronization.
However, a `helper is available `_ on the client instance.
During synchronization, only the records that changed are fetched. Depending on your implementation, attachments may have to be redownloaded completely even if only a few bytes were changed.
Publish records with attachments
--------------------------------
Files can be attached to existing records or records can be created when uploading the attachment.
Suppose that we want to attach a file (``/home/mathieu/DAFSA.bin``) to the existing record ``bec3e95c-4d28-40c1-b486-76682962861f``:
.. code-block:: bash
BUCKET=main-workspace # (or just ``main`` in Dev)
COLLECTION=public-suffix-list
RECORD=bec3e95c-4d28-40c1-b486-76682962861f
FILEPATH=/home/mathieu/DAFSA.bin
curl -X POST ${SERVER}/buckets/${BUCKET}/collections/${COLLECTION}/records/${RECORD}/attachment \
-H 'Content-Type:multipart/form-data' \
-F attachment=@$FILEPATH \
-u user:pass
And in order to create a record with both attributes and attachment, you'll have a generate a record id yourself.
.. code-block:: bash
RECORD=`uuidgen`
curl -X POST ${SERVER}/buckets/${BUCKET}/collections/${COLLECTION}/records/${RECORD}/attachment \
-H 'Content-Type:multipart/form-data' \
-F attachment=@$FILEPATH \
-F 'data={"name": "Mac Fly", "age": 42}' \
-u user:pass
.. note::
Since the dev server is open to anyone and runs on ``.mozaws.net``, we only allow certain types of files (images, audio, video, archives, ``.bin``, ``.json``, ``.gz``).
If you need to upload files with a specific extension, let us know and we will add it to the whitelist (except ``.html``, ``.js``).
Synchronize attachments
-----------------------
Attachments can be downloaded when the ``"sync"`` event is received.
.. code-block:: bash
const client = RemoteSettings("a-key");
client.on("sync", async ({ data: { created, updated, deleted } }) => {
const toDownload = created
.concat(updated.map(u => u.new))
.filter(d => d.attachment);
// Download attachments
const fileURLs = await Promise.all(
toDownload.map(entry => client.attachments.download(entry, { retries: 2 }))
);
// Open downloaded files...
const fileContents = await Promise.all(
fileURLs.map(async url => {
const r = await fetch(url);
return r.blob();
})
);
});
See more details in `client documentation `_.
About compression
-----------------
The server does not compress the files.
We plan to enable compression at the HTTP level (`Bug 1339114 `_) for when clients fetch the attachment using the ``Accept-Encoding: gzip`` request header.
In the admin tool
-----------------
The Remote Settings administration tool supports attachments as well. If a collection has a record schema and attachments are "enabled" for that collection, then editors will be able to upload attachments as part of editing records.
The controls for attachments in a given collection are in the ``attachment`` field in the collection metadata (probably located in the `remote-settings-permissions `_ repo). The ``attachment`` attribute should be an object and it can have the following properties:
- ``enabled``: boolean, true to enable attachments for this collection
- ``required``: boolean, true if records in this collection must have an attachment