# Object Storage API

The [Functions](/en/documentation/products/build/applications/functions/) Storage API is an interface that allows access to the Object Storage. Through this interface, it's possible to read and write data in the storage and its buckets.

## Class instantiation

To leverage this API, you need to import and instantiate the `Storage` class, passing the bucket's name.

### Syntax

Import: 

```javascript
import Storage from "azion:storage";
```

Instantiate: 

```js
const storage = new Storage(bucket);
```

### Parameters

| Parameter | Type | Description |
| - | - | - |
| `bucket` | string | Name of a bucket. |

:::note 
The **bucket** is created during the deploy of a static application through [Azion CLI](/en/documentation/products/azion-cli/overview/) or through [Azion API](https://api.azion.com/) requests.
:::

### Return value

Storage object used to access Object Storage.

---

## Methods

### async storage.put

The `Storage.put` method is used to insert a new object into the storage.

:::note
This is an async method and must be used with `await` or `event.waitUntil`.
:::

#### Syntax

```js
async Storage.put(key, value, options)
```

#### Parameters

| Parameter | Type | Description |
| - | - | - |
| `key` | string | Identifier that allows the search for an object in the storage |
| `value` | ArrayBuffer ou ReadableStream | Content of the object being stored. In case `value` implements a [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream), the Stream APIs can be used, and the option `content-lenght` is required |
| `options` | object | The `options` attributes are described in the table below |

**options**

To pass the `options` parameter, you must provide an object with the following attributes:

| Attribute | Type | Description |
| - | - | - |
| `content-type` | string | The `content-type` of the object being created. It's similar to the HTTP Header `content-type` and describes how the content of the bucket should be treated. `content-type` is optional. The default value is `application/octet-stream` |
| `content-length` | string | The size of the object to be created, in bytes. It's mandatory when the value is `ReadableStream` |
| `metadata` | object | Any JavaScript object containing information about the object that will be stored in the Storage. All properties of the object must be strings |

#### Return

| Success | Error |
|-|-|
| No response | Throws a `StorageError`|

#### Code sample

1. To persist the request body:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = “mybucket” 
        const storage = new Storage(bucket);
        const key = "test";
        const inputStream = event.request.body;
        let contentLength = event.request.headers.get("content-length");
        await storage.put(key, inputStream, { "content-length": contentLength });
        return new Response("OK");
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
```

2. To persist a JSON object:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const key = "test";
        const data = JSON.stringify({
            name:"John",
            address:"Abbey Road"
        });
        const buffer = new TextEncoder().encode(data);
        await storage.put(key, buffer);
        return new Response("OK");
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});

```

3. To save a JSON with metadata:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const key = "test2";
        const data = JSON.stringify({
            name:"Paul",
            address:"Abbey Road"
        });
        const buffer = new TextEncoder().encode(data);
        const options = { "content-type": "application/json",
                          "metadata": {
                            info:"test info",
                            counter: "1",
                          }}
        await storage.put(key, buffer, options);
        return new Response("OK");
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
```

---

### async storage.get(key)

The `storage.get(key)` method is used to retrieve an object.

:::note
The method is async and must be used with `await` or `event.waitUntil`.
:::

#### Syntax 

```js
async storage.get(key)
```

#### Parameters

| Parameter | Type | Description |
| - | - | - |
| `key` | string | Identifier that allows the search for an object in the bucket |

#### Return 

| Success | Error | 
|-|-|
| Returns an object of the class `StorageObject` | Throws a `StorageError`|

#### Code sample

1. To retrieve and return content from the storage:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const key = "test";
        const storageObject = await storage.get(key);
        return new Response(storageObject.content);
    }catch(error){
        return new Response(error, {status:500});
    }
}


addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
```

2. To get a JSON from the storage:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const key = "test";
        const storageObject = await storage.get(key); 
        const data = new TextDecoder().decode(await storageObject.arrayBuffer());
        return new Response(data);
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
```

3. To read an object's metadata:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const key = "test2"
        const storageObject = await storage.get(key);
        return new Response(storageObject.metadata.get("info"));   
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
``` 

---

### async storage.delete(key)

The `Storage.delete(key)` is used to remove an object from Object Storage.

:::note
This is an async method and must be used with `await` or `event.waitUntil`.
:::

#### Syntax 

```js
async Storage.delete(key)
```

#### Parameters

| Parameter | Type | Description |
| - | - | - |
| `key` | string | Identifier that allows the search for an object in the bucket |

#### Return 

| Success | Error | 
|-|-|
| No response | Throws a `StorageError`|


#### Code sample

1. To remove an object stored in Object Storage related to a specific `bucket`:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    const bucket = "mybucket";
    const storage = new Storage(bucket);
    const key = "test";
    try{
        await storage.delete(key);
    }catch(error){
        return new Response(error, {status:500});
    }
    return new Response("Ok");
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
```

---

### async storage.list()

The `Storage.list()` method is used to list all objects belonging to the specific `bucket`.

:::note
This is an async method and must be used with await or event.waitUntil.
:::

#### Syntax 

```js
await storage.list()
```

#### Return 

| Success | Error | 
|-|-|
| Returns an object of the class StorageObjectList | It throws a `StorageError`|


#### Code sample

1. Listing objects from Azion Storage:

```js
import Storage from "azion:storage";

async function handleRequest(event) {
    try{
        const bucket = "mybucket";
        const storage = new Storage(bucket);
        const objectsList = await storage.list();
        for (const entry of objectsList.entries) {
            console.log(`key: ${entry.key} length: ${entry.content_length}`);
        }
        return new Response("Ok");   
    }catch(error){
        return new Response(error, {status:500});
    }
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event));
});
``` 

---

### StorageObject Class Methods

| Method | Description |
|-|-|
| `StorageObject.content` | Read-only property containing a ReadableStream for the content stored in the storage |
| `async StorageObject.arrayBuffer()` | Asynchronous function that returns an ArrayBuffer with the content stored in the storage. This method consumes the ReadableStream from the content property |
| `StorageObject.metadata` | Read-only property containing a [Map object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) with the metadata of the object stored in the storage |
| `StorageObject.contentType` | Read-only property containing the `content-type` of the content stored in the storage |
| `StorageObject.contentLength` |  Read-only property containing the size in bytes of the content stored in the storage |