Volledige gids voor het uploaden van bestanden naar Blue met behulp van GraphQL-mutaties of REST API
Overzicht
Deze gids laat zien hoe je bestanden naar Blue kunt uploaden met twee verschillende benaderingen:
- Directe GraphQL Upload (Aanbevolen) - Eenvoudige upload in één stap met een bestandsgrootte limiet van 256MB
- REST API Upload - Drie-stappenproces dat grotere bestanden tot 4.8GB ondersteunt
Dit is een vergelijking van de twee methoden:
Kenmerk | GraphQL Upload | REST API Upload |
---|---|---|
Complexity | Simple (one request) | Complex (three steps) |
File Size Limit | 256MB per file | 4.8GB per file |
Batch Upload | Up to 10 files | Single file only |
Implementation | Direct mutation | Multi-step process |
Best For | Most use cases | Large files only |
GraphQL Bestanden Upload
De GraphQL uploadmethode biedt een eenvoudige, directe manier om bestanden met één enkele aanvraag te uploaden.
uploadFile
Uploadt een enkel bestand naar het bestandopslagsysteem en maakt een bestandsreferentie in de database.
Invoer:
file: Upload!
- Het bestand dat geüpload moet worden (met multipart/form-data)projectId: String!
- Project-ID of slug waar het bestand zal worden opgeslagencompanyId: String!
- Bedrijf-ID of slug waar het bestand zal worden opgeslagen
Retourneert: File!
- Het gemaakte bestandsobject
Voorbeeld:
mutation UploadFile($input: UploadFileInput!) {
uploadFile(input: $input) {
id
uid
name
size
type
extension
shared
createdAt
project {
id
name
}
folder {
id
title
}
}
}
uploadFiles
Uploadt meerdere bestanden naar het bestandopslagsysteem en maakt bestandsreferenties in de database.
Invoer:
files: [Upload!]!
- Array van bestanden om te uploaden (max 10)projectId: String!
- Project-ID of slug waar de bestanden zullen worden opgeslagencompanyId: String!
- Bedrijf-ID of slug waar de bestanden zullen worden opgeslagen
Retourneert: [File!]!
- Array van gemaakte bestandsobjecten
Voorbeeld:
mutation UploadFiles($input: UploadFilesInput!) {
uploadFiles(input: $input) {
id
uid
name
size
type
extension
shared
createdAt
}
}
Client Implementatie
Apollo Client (JavaScript)
Enkele Bestandsupload:
import { gql } from '@apollo/client';
const UPLOAD_FILE = gql`
mutation UploadFile($input: UploadFileInput!) {
uploadFile(input: $input) {
id
uid
name
size
type
extension
shared
createdAt
}
}
`;
// Using file input
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const { data } = await uploadFile({
variables: {
input: {
file: file,
projectId: "project_123", // or "my-project-slug"
companyId: "company_456" // or "my-company-slug"
}
}
});
@@CB##22b52cd2-544b-470b-8e00-31206113160c##CB@@javascript
const UPLOAD_FILES = gql`
mutation UploadFiles($input: UploadFilesInput!) {
uploadFiles(input: $input) {
id
uid
name
size
type
extension
shared
createdAt
}
}
`;
// Using multiple file inputs
const fileInputs = document.querySelectorAll('input[type="file"]');
const files = Array.from(fileInputs).map(input => input.files[0]).filter(Boolean);
const { data } = await uploadFiles({
variables: {
input: {
files: files,
projectId: "project_123", // or "my-project-slug"
companyId: "company_456" // or "my-company-slug"
}
}
});
Vanilla JavaScript
Single File Upload:
<!-- HTML -->
<input type="file" id="fileInput" />
<button onclick="uploadFile()">Upload File</button>
async function uploadFile() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert('Please select a file');
return;
}
// Create GraphQL mutation
const query = `
mutation UploadFile($input: UploadFileInput!) {
uploadFile(input: $input) {
id
name
size
type
extension
createdAt
}
}
`;
// Prepare form data
const formData = new FormData();
formData.append('operations', JSON.stringify({
query: query,
variables: {
input: {
file: null, // Will be replaced by file
projectId: "your_project_id", // or "your-project-slug"
companyId: "your_company_id" // or "your-company-slug"
}
}
}));
formData.append('map', JSON.stringify({
"0": ["variables.input.file"]
}));
formData.append('0', file);
try {
const response = await fetch('/graphql', {
method: 'POST',
body: formData,
headers: {
// Don't set Content-Type - let browser set it with boundary
'Authorization': 'Bearer your_auth_token'
}
});
const result = await response.json();
if (result.errors) {
console.error('Upload failed:', result.errors);
alert('Upload failed: ' + result.errors[0].message);
} else {
console.log('Upload successful:', result.data.uploadFile);
alert('File uploaded successfully!');
}
} catch (error) {
console.error('Network error:', error);
alert('Network error during upload');
}
}
Multiple Files Upload:
<!-- HTML -->
<input type="file" id="filesInput" multiple />
<button onclick="uploadFiles()">Upload Files</button>
async function uploadFiles() {
const filesInput = document.getElementById('filesInput');
const files = Array.from(filesInput.files);
if (files.length === 0) {
alert('Please select files');
return;
}
if (files.length > 10) {
alert('Maximum 10 files allowed');
return;
}
const query = `
mutation UploadFiles($input: UploadFilesInput!) {
uploadFiles(input: $input) {
id
name
size
type
extension
createdAt
}
}
`;
const formData = new FormData();
// Create file placeholders for variables
const fileVariables = files.map((_, index) => null);
formData.append('operations', JSON.stringify({
query: query,
variables: {
input: {
files: fileVariables,
projectId: "your_project_id", // or "your-project-slug"
companyId: "your_company_id" // or "your-company-slug"
}
}
}));
// Create map for file replacements
const map = {};
files.forEach((_, index) => {
map[index.toString()] = [`variables.input.files.${index}`];
});
formData.append('map', JSON.stringify(map));
// Append actual files
files.forEach((file, index) => {
formData.append(index.toString(), file);
});
try {
const response = await fetch('/graphql', {
method: 'POST',
body: formData,
headers: {
'Authorization': 'Bearer your_auth_token'
}
});
const result = await response.json();
if (result.errors) {
console.error('Upload failed:', result.errors);
alert('Upload failed: ' + result.errors[0].message);
} else {
console.log('Upload successful:', result.data.uploadFiles);
alert(`${result.data.uploadFiles.length} bestanden succesvol geüpload!`);
}
} catch (error) {
console.error('Network error:', error);
alert('Network error during upload');
}
}
cURL Example
# Single file upload with cURL
curl -X POST \
-H "Authorization: Bearer your_auth_token" \
-F 'operations={"query":"mutation UploadFile($input: UploadFileInput!) { uploadFile(input: $input) { id name size type extension createdAt } }","variables":{"input":{"file":null,"projectId":"your_project_id","companyId":"your_company_id"}}}' \
-F 'map={"0":["variables.input.file"]}' \
-F '0=@/path/to/your/file.jpg' \
https://your-api.com/graphql
REST API Upload
Use this method for files larger than 256MB (up to 4.8GB). This approach uses a three-step process: request upload credentials, upload to storage, then register the file in the database.
Prerequisites:
- Python 3.x installed
requests
library installed:pip install requests
- A valid X-Bloo-Token-ID and X-Bloo-Token-Secret for Blue API authentication
- The file to upload (e.g., test.jpg) in the same directory as the script
This method covers two scenarios:
- Uploading to the "File Tab"
- Uploading to the "Todo File Custom Field"
Configuration
Define these constants at the top of your script:
@@CB##89d1da4f-bfad-46a0-9a65-cd2faa18fe49##CB@@
This is diagram that shows the flow of the upload process:
Uploading to File Tab
::code-group
@@CB##4877589c-9106-41df-8463-3b1e0a9c0e48##CB@@
::
Steps Explained
Step 1: Request Upload Credentials
- Send a GET request to
https://api.blue.cc/uploads?filename=test.jpg
- Returns S3 credentials in JSON format
Sample Response:
@@CB##977092d1-a543-4aa1-bf3b-428b04b5a345##CB@@
Step 2: Upload File to S3
- Uses the
files
parameter inrequests.post@@CODE##c3db125d-0ef0-40ec-ba4b-97e291cdda09##CODE@@https://api.blue.cc/graphql@@CODE##8ea6c34d-d2be-48f7-9ea4-dc6c86899013##CODE@@os.path.getsize@@CODE##33d98706-233d-438b-9adb-2f21d140e622##CODE@@todoId
andcustomFieldId
specific to your setup
Sample Response:
{
"data": {
"createTodoCustomFieldFile": true
}
}