A unique and powerful feature included with the IPFS API and Private IPFS API is the key-value store. Anytime you upload or update a file you can store up to 10 key-value pairs.

const upload = await pinata.upload.public
  .file(file)
  .keyvalues({
    env: "prod",
    userId: "abc123"
  })

This small yet powerful feature allows you to remove the need for an external database in most cases. We like to call this paradigm File-Centric Architecture, where apps and their structure revolves around the files themselves. This creates a molecule like structure and keeps the data related to the file close by.

Creating

Creating a new key-value for a file can be done in two ways:

Uploading a File

By including the key-values as part of the upload method or endpoint and the file and the key-values will be created at the same time.

const upload = await pinata.upload.public
  .file(file)
  .keyvalues({
    env: "prod",
    userId: "abc123"
  })

Updating an Existing File

If you’ve already uploaded a file and want to add a key-value you can do so with the update method or endpoint.

const update = await pinata.files.public.update({
  id: "2b4ee88d-1032-4e4e-a373-97d1ab127f16", // Target File ID
  keyvalues: {
    env: "prod",
    userId: "abc123"
  }
})

Retrieving

Since key-values exist with files, you can retrieve them by listing files either through the SDK method or API endpoint, and filtering results by key-value. The operator will always be ===.

You can chain multiple key-value queries together and it will only return files that meet both values.

const files = await pinata.files.public
  .list()
  .keyvalues({
    user: "abc123"
  })

Updating

The key-value system will automatically detect if you are replacing an existing value for a given key. For example, if you have a key of env with a value of prod, if you make an update of env: "dev" it will replace the old value. If the key does not exist then it will make a new key-value entry.

const update = await pinata.files.public.update({
  id: "2b4ee88d-1032-4e4e-a373-97d1ab127f16", // Target File ID
  keyvalues: {
    env: "dev", // Previously `prod`
  }
})

Deleting

You can remove a key-value entry by making the value null.

const update = await pinata.files.public.update({
  id: "2b4ee88d-1032-4e4e-a373-97d1ab127f16", // Target File ID
  keyvalues: {
    env: null, // Deletes the `env` key-value entry
  }
})

Further Reading

Check out some of our reading material on some of the possibilities of key-values and file-centric architecture!