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:

  1. Directe GraphQL Upload (Aanbevolen) - Eenvoudige upload in één stap met een bestandsgrootte limiet van 256MB
  2. 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 opgeslagen
  • companyId: 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 opgeslagen
  • companyId: 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:

  1. Uploading to the "File Tab"
  2. 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:

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 in requests.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 and customFieldId specific to your setup

Sample Response:

{
  "data": {
    "createTodoCustomFieldFile": true
  }
}

AI Assistent

Antwoorden worden gegenereerd met behulp van AI en kunnen fouten bevatten.

Hoe kan ik u helpen?

Vraag me alles over Blue of deze documentatie.

Voer in om te verzenden • Shift+Enter voor nieuwe regel • ⌘I om te openen