vai al contenuto principale

Lavorare con file

Le API GraphQL della Cloudlet consentono di recuperare riferimenti a file pre-esistenti e associare file temporanei al grafo di oggetti. L'upload/download effettivo dei file richiede l'interazione con servizi esterni allo schema GraphQL, offerti dalla Cloudlet come risorse REST.

Un file binario persistito in Livebase dipende dalla classe su cui è dichiarato l’attributo file, dal nome dell’attributo e dall’ID dello specifico oggetto/record della classe. Sostanzialmente, gli attributi di tipo file in GraphQL restituiscono una rappresentazione intermedia dei File binari, contenente metadati e riferimenti (link) alla risorse effettive; i file binari veri e propri sono mappati su risorse REST dedicate.

Anche l’aggiunta di nuovi file è un processo in due passi: la Cloudlet espone un servizio REST per l’upload del file binario, che restituisce un riferimento temporaneo al file (PendingFileReference); questa struttura deve essere comunicata con una mutation GraphQL per associare il file temporaneo (non ancora legato al grafo) a un dato oggetto con un attributo file, rendendo così il file persistente nel sistema.

Lavorare con file

L’upload e il download di File binari avviene esternamente a GraphQL, mediante endpoint REST dedicati della Cloudlet.

La gestione dei file in GraphQL è strutturata in questo modo in previsione di un futuro supporto di Livebase all’upload di file verso servizi esterni; attualmente i File binari effettivi (temporanei e non) sono persistiti sul database della Cloudlet in una tabella riservata.

Modello di riferimento #

Tutti gli esempi in questa pagina fanno riferimento alla classe Employee in figura, e in particolare all’attributo identity_card cerchiato in rosso:

Employee

La classe Employee, come modellata nel Tutorial, a cui è stato aggiunto l’attributo identity_card di tipo file.

Recuperare file esistenti #

I passi necessari per recuperare un file esistente sono:

  1. Leggere il riferimento al file via GraphQL;
  2. Richiedere il download del file via REST.

Leggere riferimenti a file #

È possibile recuperare riferimenti a file tramite tutti i servizi dello schema che ritornano la struttura <ClassName>, vale a dire tutti i servizi di lettura e i servizi di scrittura di tipo create/update/save e preview.

Su type <ClassName>, attributi di tipo file sono mappati nella seguente struttura FileInfo:

type FileInfo {
  fileId: ID!
  link: String!
  mimeType: String!
  name: String!
  size: Int!
  uploadedOn(format: String = "default"): Datetime!
}

Il campo fileId contiene un identificatore univoco del file persistito e associato a un oggetto esistente di <ClassName>; il campo link contiene l’URI della risorsa REST che consente il download del file binario. I campi rimanenti contengono metadati e altre informazioni, come la data di upload del file.

Per Employee si ha dunque la seguente struttura Employee:

type Employee {
  _id: ID!
  identity_card: FileInfo

  # attributi, ruoli uscenti, associabili ...
  # ...
}

Per scaricare il file è quindi necessario ottenere il link invocando un qualunque servizio che restituisce Employee, ad esempio usando il servizio get:

{
  Employee___get(_id: "10101") {
    _id
    identity_card {
      fileId
      link
      mimeType
      name
      size
      uploadedOn
    }
  }
}
{
"data": {
"Employee___get": {
"_id": "10101",
"identity_card" {
"fileId": "101865",
"link": "https://hs4.fhoster.com/JohnDoe/Workforce/auth/file/employee/10101/identity_card",
"mimeType": "image/png",
"name": "MyCurriculum.png",
"size": 68731,
"uploadedOn": "10/10/2020 12:05:40"
}
}
}
}

Richiedere il download di file #

La Cloudlet offre i seguenti endpoint REST per il download di file binari, sotto la radice auth/file:

https://<CloudletURL>/auth/file/<ClassName>/<EntityID>/<FileAttributeName>

Ciascun endpoint consente di scaricare il file binario associato all’attributo <FileAttributeName> di un’istanza della classe <ClassName> (identificata dal suo ID, <EntityID>).

Come affermato qui, <CloudletURL> dipende dal dominio su cui la Cloudlet è dispiegata, dallo username dell’account proprietario e dal nome della Cloudlet. Ad esempio, data la Cloudlet Workforce dell’account JohnDoe, e considerato l’attributo identity_card di Employee dell’oggetto con ID 10101, l’endpoint corrispondente è:

https://hs4.fhoster.com/JohnDoe/Workforce/auth/file/employee/10101/identity_card

Il file può essere recuperato con una chiamata HTTP di tipo GET, autenticata come descritto qui. Ad esempio, con cURL:

curl --output $MY_FILE -L "$MY_ENDPOINT" \
 -H "Authorization: Basic $MY_TOKEN"

Aggiungere file #

I passi necessari per aggiungere un nuovo file sono:

  1. Effettuare l’upload del file via REST e ottenere un riferimento al pending file;
  2. Associare il pending file all’oggetto desiderato via GraphQL, comunicando il riferimento al pending file.

Effettuare l’upload di pending file #

La Cloudlet offre i seguenti endpoint REST per l’upload di file binari, sotto la radice auth/file:

https://<CloudletURL>/auth/file/<ClassName>/<FileAttributeName>

Ciascun endpoint consente di caricare un file binario che verrà successivamente associato all’attributo <FileAttributeName> di un’istanza della classe <ClassName>.

Come affermato qui, <CloudletURL> dipende dal dominio su cui la Cloudlet è dispiegata, dallo username dell’account proprietario e dal nome della Cloudlet. Ad esempio, data la Cloudlet Workforce dell’account JohnDoe, e considerato l’attributo identity_card di Employee, l’endpoint corrispondente è:

https://hs4.fhoster.com/JohnDoe/Workforce/auth/file/employee/identity_card

Il file può essere caricato con una chiamata HTTP di tipo POST, autenticata come descritto qui e contenente multipart data, con chiave file. Ad esempio, con cURL è sufficiente includere il flag -F e usare la sintassi @ per fare riferimento a un file locale:

curl -i "$MY_ENDPOINT" \
 -H "Authorization: Basic $MY_TOKEN" \
 -F "file=@$INPUT_FILE"

In risposta, il server restituirà un oggetto JSON contenente il riferimento al file appena caricato, che si trova nello stato pending:

{
  "pendingFileId": "d5b6106abe7c34f1d6560f4a922ba9313f3a6b20519251",
  "fileId": "519251",
  "name": "MyCurriculum.png",
  "mimeType": "image/png",
  "size": 68731,
  "uploadedOn": "10/10/2020 12:05:40"
}

Ciclo di vita dei pending file #

I pending file vengono persistiti sul database della Cloudlet; rimangono in questo stato per un’ora, allo scadere della quale vengono rimossi. È compito dello sviluppatore associare il pending file a un oggetto, mediante GraphQL o via Plugin.

Durante questo periodo, i pending file sono disponibili al download. La Cloudlet espone i seguenti endpoint REST per il download di pending file:

https://<CloudletURL>/auth/file/<ClassName>/<FileAttributeName>/pending/<pendingFileId>

dove <pendingFileId> è l’ID restituito nel JSON mostrato sopra dal servizio di upload. Una volta legato il file a un oggetto, il servizio di download per quel pendingFileId non è più disponibile.

Associare pending file #

Il JSON restituito dal servizio REST per l’upload è codificato in GraphQL nell’input type PendingFileReference:

input PendingFileReference {
  pendingFileId: String!
  fileId: ID!
  mimeType: String!
  name: String!
  size: Int!
  uploadedOn: Datetime!
}

Questo input è mappato su tutti gli attributi di tipo file presenti negli input type richiesti dai servizi di scrittura che creano o modificano informazioni (create, update o save).

Prendendo come esempio l’input <ClassName>Create, per Employee si ha la seguente struttura EmployeeCreate:

input EmployeeCreate {
  identity_card: PendingFileReference

  # attributi, ruoli uscenti ...
  # ...
}

Tutti i campi dell’input sono obbligatori !. Per associare il pending file, è sufficiente includere in una mutation il JSON restituito dal servizio REST per l’upload. A tale scopo, può essere comodo usare una variabile per sostituire in blocco l’input PendingFileReference:

query($file_reference: PendingFileReference!) {
  Employee___update(
    data: {
      _id: "10101",
      identity_card: $file_reference
    }
  ) {
    _id
    full_name
    identity_card {
      fileId
      link
      mimeType
      name
      size
      uploadedOn
    }
  }
}
{
  "file_reference": {
    "pendingFileId": "d5b6106abe7c34f1d6560f4a922ba9313f3a6b20519251",
    "fileId": "519251",
    "name": "MyCurriculum.png",
    "mimeType": "image/png",
    "size": 68731,
    "uploadedOn": "10/10/2020 12:05:40"
  }
}

Il servizio REST per l’upload di file è:

POST https://<CloudletURL>/auth/file/<ClassName>/<FileAttributeName>

Il servizio REST per il download di pending file è:

GET https://<CloudletURL>/auth/file/<ClassName>/<FileAttributeName>/pending/<pendingFileId>

Il servizio REST per il download di file persistiti sul database della Cloudlet è:

GET https://<CloudletURL>/auth/file/<ClassName>/<EntityID>/<FileAttributeName>