|
| 1 | +export const metadata = { |
| 2 | + title: 'Object', |
| 3 | + description: |
| 4 | + "On this page, we'll dive into objects, and how to access them through the Web API.", |
| 5 | +} |
| 6 | + |
1 | 7 | # Objects
|
2 | 8 |
|
3 |
| -Under construction. |
| 9 | +Objects are Drop-generated binary blobs with attached metadata. They are used to store images, downloads, and similar files. {{ className: 'lead' }} |
| 10 | + |
| 11 | +## Authentication |
| 12 | + |
| 13 | +Objects don't inherently require authentication, but generally do. Object ACLs are one of three values: |
| 14 | + |
| 15 | +- `anonymous`: Anyone can access it. The object doesn't require authentication. |
| 16 | +- `internal`: Anyone with an account can access it. As long as you have a valid session or User token, you can access it. |
| 17 | +- `[userId]`: Only a specific user can access it, based on the user ID. |
| 18 | + |
| 19 | +As long with one of these values, one of the following CRUD operations can be append: |
| 20 | + |
| 21 | +- `read`: Read access to the object. |
| 22 | +- `write`: Update/overwrite access to the object. |
| 23 | +- `delete`: Delete access to the object. |
| 24 | + |
| 25 | +Putting these together, we get ACLs like: |
| 26 | + |
| 27 | +- `anonymous:read` |
| 28 | +- `[userId]:write` |
| 29 | +- `internal:write` |
| 30 | + |
| 31 | +**However, these kinds of operations are rarely handled by the object system, for various reasons.** Generally only `read` permissions are granted at an object-level, and then endpoints update object IDs internally. |
| 32 | + |
| 33 | +## Object metadata |
| 34 | + |
| 35 | +Alongside a raw binary blob, objects store various bits of metadata, which are used internally for various purposes. As an API consumer, you don't have access to most of this metadata directly, but it is exposed in the behaviour of various routes. |
| 36 | + |
| 37 | +### Properties |
| 38 | + |
| 39 | +<Properties> |
| 40 | + <Property name="mime" type="string"> |
| 41 | + MIME type of the data. This type is returned in the `Content-Type` header |
| 42 | + for fetch requests of objects. Read about [MIME types on the |
| 43 | + MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types). |
| 44 | + </Property> |
| 45 | + <Property name="permissions" type="string[]"> |
| 46 | + List of ACLs as described above. They define what operations are permitted |
| 47 | + and not permitted on objects. |
| 48 | + </Property> |
| 49 | + <Property name="userMetadata" type="string"> |
| 50 | + Additional metadata. Despite the name, this metadata is not provided by, |
| 51 | + you, the user, but instead by consumers of the internal object API, who is |
| 52 | + 'user' instead. Essentially, this metadata is per-object and per-usecase |
| 53 | + specific. It is not exposed. |
| 54 | + </Property> |
| 55 | +</Properties> |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +## Check object {{ tag: 'HEAD', label: '/api/v1/object/:id', apilevel: "user", acl: "object:read" }} |
| 60 | + |
| 61 | +<Row> |
| 62 | + <Col> |
| 63 | + |
| 64 | + This endpoint is used by browsers to check `ETag` values for client-side caching. It only sets ETag headers, not `Content-Type`. |
| 65 | + |
| 66 | + The above ACL isn't *required* to access internal resources, only if you want to access user-restricted objects. |
| 67 | + |
| 68 | + </Col> |
| 69 | + <Col sticky> |
| 70 | + |
| 71 | + <CodeGroup title="Request" tag="HEAD" label="/api/v1/object/:id"> |
| 72 | + |
| 73 | + ```bash {{ title: 'cURL' }} |
| 74 | + curl -I http://localhost:3000/api/v1/object/{id} \ |
| 75 | + -H "Authorization: Bearer {token}" |
| 76 | + ``` |
| 77 | + |
| 78 | + ```js |
| 79 | + const response = await fetch("http://localhost:3000/api/v1/object/{id}", { |
| 80 | + headers: { |
| 81 | + Authorization: "Bearer {token}" |
| 82 | + }, |
| 83 | + method: "HEAD" |
| 84 | + }); |
| 85 | + |
| 86 | + ``` |
| 87 | + |
| 88 | + </CodeGroup> |
| 89 | + |
| 90 | + ``` {{ title: 'Response' }} |
| 91 | + No response returned. |
| 92 | + ``` |
| 93 | + |
| 94 | + </Col> |
| 95 | +</Row> |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## Fetch object {{ tag: 'GET', label: '/api/v1/object/:id', apilevel: "user", acl: "object:read" }} |
| 100 | + |
| 101 | +<Row> |
| 102 | + <Col> |
| 103 | + |
| 104 | + This endpoint fetches a binary stream of the object's content. It sets both ETag headers and `Content-Type` for proper rendering within browsers. |
| 105 | + |
| 106 | + The above ACL isn't *required* to access internal resources, only if you want to access user-restricted objects. |
| 107 | + |
| 108 | + </Col> |
| 109 | + <Col sticky> |
| 110 | + |
| 111 | + <CodeGroup title="Request" tag="GET" label="/api/v1/object/:id"> |
| 112 | + |
| 113 | + ```bash {{ title: 'cURL' }} |
| 114 | + curl -G http://localhost:3000/api/v1/object/{id} \ |
| 115 | + -H "Authorization: Bearer {token}" \ |
| 116 | + --output myfile.bin |
| 117 | + ``` |
| 118 | + |
| 119 | + ```js |
| 120 | + const response = await fetch("http://localhost:3000/api/v1/object/{id}", { |
| 121 | + headers: { |
| 122 | + Authorization: "Bearer {token}" |
| 123 | + }, |
| 124 | + }); |
| 125 | + |
| 126 | + const object = await response.blob(); |
| 127 | + |
| 128 | + ``` |
| 129 | + |
| 130 | + </CodeGroup> |
| 131 | + |
| 132 | + ``` {{ title: 'Response' }} |
| 133 | + < ... binary stream of object contents ...> |
| 134 | + ``` |
| 135 | + |
| 136 | + </Col> |
| 137 | +</Row> |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## Update object {{ tag: 'POST', label: '/api/v1/object/:id', apilevel: "user", acl: "object:update" }} |
| 142 | + |
| 143 | +<Row> |
| 144 | + <Col> |
| 145 | + |
| 146 | + This endpoint overwrites an object in-place (the ID doesn't change). It's rarely used, as endpoint generally handle uploads themselves. |
| 147 | + |
| 148 | + The above ACL isn't *required* to access internal resources, only if you want to access user-restricted objects. |
| 149 | + |
| 150 | + </Col> |
| 151 | + <Col sticky> |
| 152 | + |
| 153 | + <CodeGroup title="Request" tag="POST" label="/api/v1/object/:id"> |
| 154 | + |
| 155 | + ```bash {{ title: 'cURL' }} |
| 156 | + curl -X POST http://localhost:3000/api/v1/object/{id} \ |
| 157 | + -H "Authorization: Bearer {token}" \ |
| 158 | + --data-binary "@myfile.bin" |
| 159 | + ``` |
| 160 | + |
| 161 | + ```js |
| 162 | + const response = await fetch("http://localhost:3000/api/v1/object/{id}", { |
| 163 | + headers: { |
| 164 | + Authorization: "Bearer {token}" |
| 165 | + }, |
| 166 | + method: "POST", |
| 167 | + body: Buffer.from(...) |
| 168 | + }); |
| 169 | + |
| 170 | + |
| 171 | + ``` |
| 172 | + |
| 173 | + </CodeGroup> |
| 174 | + |
| 175 | + ```json {{ title: 'Response' }} |
| 176 | + { |
| 177 | + "success": true |
| 178 | + } |
| 179 | + ``` |
| 180 | + |
| 181 | + </Col> |
| 182 | +</Row> |
| 183 | + |
| 184 | +--- |
| 185 | + |
| 186 | +## Delete object {{ tag: 'DELETE', label: '/api/v1/object/:id', apilevel: "user", acl: "object:delete" }} |
| 187 | + |
| 188 | +<Row> |
| 189 | + <Col> |
| 190 | + |
| 191 | + This endpoint deletes an object by ID. Again, it is rarely used, as individual endpoints handle object deletions themselves. |
| 192 | + |
| 193 | + The above ACL isn't *required* to access internal resources, only if you want to access user-restricted objects. |
| 194 | + |
| 195 | + </Col> |
| 196 | + <Col sticky> |
| 197 | + |
| 198 | + <CodeGroup title="Request" tag="DELETE" label="/api/v1/object/:id"> |
| 199 | + |
| 200 | + ```bash {{ title: 'cURL' }} |
| 201 | + curl -X DELETE http://localhost:3000/api/v1/object/{id} \ |
| 202 | + -H "Authorization: Bearer {token}" |
| 203 | + ``` |
| 204 | + |
| 205 | + ```js |
| 206 | + const response = await fetch("http://localhost:3000/api/v1/object/{id}", { |
| 207 | + headers: { |
| 208 | + Authorization: "Bearer {token}" |
| 209 | + }, |
| 210 | + method: "DELETE", |
| 211 | + }); |
| 212 | + |
| 213 | + |
| 214 | + ``` |
| 215 | + |
| 216 | + </CodeGroup> |
| 217 | + |
| 218 | + ```json {{ title: 'Response' }} |
| 219 | + { |
| 220 | + "success": true |
| 221 | + } |
| 222 | + ``` |
| 223 | + |
| 224 | + </Col> |
| 225 | +</Row> |
| 226 | + |
| 227 | +--- |
| 228 | + |
| 229 | +## Object cleanup |
| 230 | + |
| 231 | +It is important to note that there is a scheduled task on Drop instances that cleans up unreferenced objects. It automatically deletes objects unreferenced in the database, but it may not function correctly. If you find that objects are disappearing on you, please [file a bug report](https://github.com/Drop-OSS/drop/issues). |
0 commit comments